# 通话前检测 (/zh-CN/realtime-media/rtc/build/optimize-and-operate/lastmile-quality/macos)

> For AI agents: see the complete documentation index at [llms.txt](/llms.txt).

在视频会议、在线教育、互动直播等对通信质量要求高的场景下，进行通话前检测可以帮助提前识别并排查问题，保证实时互动体验。

## 功能介绍 [#功能介绍-2]

通话前检测通常可以从**设备质量检测**和**网络质量探测**两个角度开展。

- **设备质量检测**：包括检测本地麦克风、扬声器以及摄像头是否能正常工作。
- **网络质量探测**：可以向用户反馈上下行 last mile 网络的带宽、丢包、网络抖动和往返时延数据，从而判断当前网络状态是否良好。其中，**last mile** 指的是声网边缘服务器和终端用户设备之间通信的“最后一公里”，last mile 网络质量影响用户发送和接收音视频的流畅度和清晰度。

## 前提条件 [#前提条件-2]

在进行通话前检测之前，请确保你已在 App 中实现了基本的实时音视频功能，且 App 已获取相关设备的使用权限。请参考[实现音视频互动](/zh-CN/realtime-media/rtc/get-started/quick-start)。

## 实现步骤 [#实现步骤-2]

参考以下步骤在 App 中实现通话前检测。

### 设备质量检测 [#设备质量检测-2]

设备质量检测的基本流程如下：

<DocsImage alt="设备质量检测流程图" src="https://web-cdn.agora.io/docs-portal/img/rtc/echotest.svg" displayWidth="50%" />

SDK 提供了 `startEchoTestWithConfig` 方法，用于测试网络连接和音视频设备是否正常工作。参考以下步骤实现设备质量检测：

1. 在加入频道前，调用 `startEchoTestWithConfig`，并在 `EchoTestConfiguration` 中配置测试的对象、频道名和返回测试结果的时间间隔。
2. 开始测试后，用户需发出声音或面对摄像头，音频或视频默认会在约 2 秒后播放出来。如果音频播放正常，则表示系统音频设备和用户上下行网络均正常；如果视频播放正常，则表示系统视频设备和用户上下行网络均正常。
3. 获得测试结果后，调用 `stopEchoTest` 停止测试，然后再调用 `joinChannel` 加入频道。

:::warning[注意]
目前，使用 `startEchoTest` 同时测试音频设备和视频设备可能导致测试结果出现短暂的音画不同步。
:::

请参考以下代码实现设备检测：

```swift
// 测试音频设备
@IBAction func doAudioTest(sender: UIButton) {
  let testConfig = AgoraEchoTestConfiguration()
  // 设置返回测试结果的时间间隔
  testConfig.intervalInSeconds = 10
  // 开启音频设备测试
  testConfig.enableAudio = true
  // 关闭视频设备测试
  testConfig.enableVideo = false
  // 标识每个测试的频道名
  testConfig.channelId = "AudioEchoTest" + "\(Int.random(in: 1...1000))"
  // 开始测试音频设备
  let ret = agoraKit.startEchoTest(withConfig: testConfig)
}

// 测试视频设备
@IBAction func doVideoTest(_ sender: UIButton) {
  let testConfig = AgoraEchoTestConfiguration()
  // 设置视频画面的延迟
  testConfig.intervalInSeconds = 2
  // 关闭音频设备测试
  testConfig.enableAudio = false
  // 开启视频设备测试
  testConfig.enableVideo = true
  // 标识每个测试的频道名
  testConfig.channelId = "VideoEchoTest" + "\(Int.random(in: 1...1000))"
  // 设置用于渲染本地用户视频的视图
  testConfig.view = videoCanvasView
  // 开始测试视频设备
  let ret = agoraKit.startEchoTest(withConfig: testConfig)
}
```

### 网络质量探测 [#网络质量探测-2]

网络质量探测的基本流程如下：

<DocsImage alt="网络质量探测流程图" src="https://web-cdn.agora.io/docs-portal/img/rtc/lastmile-test.svg" displayWidth="50%" />

SDK 提供了 `startLastmileProbeTest` 方法，用于在加入频道之前探测 last mile 网络质量，并返回有关网络质量打分和网络质量统计信息。参考以下步骤进行网络质量探测：

1. 在加入频道或切换用户角色之前，调用 `startLastmileProbeTest` 启动网络探测。你需要在 `LastmileProbeConfig` 中设置探测对象和预期最高码率。
2. 调用该方法后，SDK 会触发以下回调：
   - `onLastmileQuality`：在调用 `startLastmileProbeTest` 方法两秒后触发。该回调通过打分反馈上下行网络质量，更贴近主观感受。
   - `onLastmileProbeResult`：在调用 `startLastmileProbeTest` 方法 30 秒后触发。该回调返回网络状况的实时统计数据，包括丢包率、网络抖动和可用带宽，更加客观。
3. 获取网络质量统计信息后，调用 `stopLastmileProbeTest` 方法停止 last mile 网络检测。

请参考以下代码实现网络质量探测：

```swift
// 创建网络探测配置对象
let config = AgoraLastmileProbeConfig()
// 检测上行网络
config.probeUplink = true;
// 检测下行网络
config.probeDownlink = true;
// 预期的上行比特率 (bps)。取值范围为 [100000,5000000]
config.expectedUplinkBitrate = 100000;
// 预期的下行比特率 (bps)。取值范围为 [100000,5000000]
config.expectedDownlinkBitrate = 100000;

// 开始网络质量探测
agoraKit.startLastmileProbeTest(config)

// 定义回调函数用于接收网络质量统计信息
func rtcEngine(_ engine: AgoraRtcEngineKit, lastmileQuality quality: AgoraNetworkQuality) {
    lastmileResultLabel.text = "Quality: \(quality.description())"
}
func rtcEngine(_ engine: AgoraRtcEngineKit, lastmileProbeTest result: AgoraLastmileProbeResult) {
  // 往返时延
  let rtt = "Rtt: \(result.rtt)ms"
  // 下行网络带宽
  let downlinkBandWidth = "DownlinkAvailableBandwidth: \(result.downlinkReport.availableBandwidth)Kbps"
  // 下行抖动缓冲区
  let downlinkJitter = "DownlinkJitter: \(result.downlinkReport.jitter)ms"
  // 下行丢包率
  let downlinkLoss = "DownlinkLoss: \(result.downlinkReport.packetLossRate)%"
  // 上行网络带宽
  let uplinkBandwidth = "UplinkAvailableBandwidth: \(result.uplinkReport.availableBandwidth)Kbps"
  // 上行抖动缓冲区
  let uplinkJitter = "UplinkJitter: \(result.uplinkReport.jitter)ms"
  // 上行丢包率
  let uplinkLoss = "UplinkLoss: \(result.uplinkReport.packetLossRate)%"

  lastmileProbResultLabel.text = [rtt, downlinkBandwidth, downlinkJitter, downlinkLoss,uplinkBandwidth,uplinkJitter,uplinkLoss].joined(separator: "\n")
}

// 停止网络质量探测
agoraKit.stopLastmileProbeTest()
```

## 参考信息 [#参考信息-2]

### 检测异常处理建议 [#检测异常处理建议-2]

在确保 API 正确调用的前提下，遇到检测异常时，声网推荐你参考下表采取措施：

| 异常现象 | 解决方案 |
| --- | --- |
| 检测音频设备时听不到声音 | [lastmile-quality-macos-markdown-0-1-1 details](#table-slot-lastmile-quality-macos-markdown-0-1-1) |
| 检测视频设备时看不到画面 | [lastmile-quality-macos-markdown-0-2-1 details](#table-slot-lastmile-quality-macos-markdown-0-2-1) |
| 检测到上行网络质量不佳（丢包率 > 5%；网络抖动 > 100ms） | [lastmile-quality-macos-markdown-0-3-1 details](#table-slot-lastmile-quality-macos-markdown-0-3-1) |
| 检测到下行网络质量不佳（丢包率 > 5%；网络抖动 > 100ms） | [lastmile-quality-macos-markdown-0-4-1 details](#table-slot-lastmile-quality-macos-markdown-0-4-1) |

<a id="table-slot-lastmile-quality-macos-markdown-0-1-1"></a>

**lastmile-quality-macos-markdown-0-1-1 details**

- 检查录制设备和播放设备是否正常工作、是否被其他程序占用。
- 检查网络连接是否正常。

<a id="table-slot-lastmile-quality-macos-markdown-0-2-1"></a>

**lastmile-quality-macos-markdown-0-2-1 details**

- 检查视频设备是否正常工作、是否被其他程序占用。
- 检查网络连接是否正常。

<a id="table-slot-lastmile-quality-macos-markdown-0-3-1"></a>

**lastmile-quality-macos-markdown-0-3-1 details**

- 检查本地网络是否正常。
- 通过降低分辨率或降低帧率等方法确保发布音视频流的码率不超过上行可用带宽。你可以参考[视频参数推荐值](/zh-CN/realtime-media/rtc/build/video/video-profile#视频参数推荐值)和[视频属性参考表](/zh-CN/realtime-media/rtc/build/video/video-profile#分辨率帧率和码率)进行设置。

<a id="table-slot-lastmile-quality-macos-markdown-0-4-1"></a>

**lastmile-quality-macos-markdown-0-4-1 details**

- 检查本地网络是否正常。
- 通过以下方式确保本地订阅的总带宽不超过下行可用带宽：

  - 减少接收端订阅音视频流的数量或降低发送端发布音视频流的码率。
  - 在发送端启用[双流模式](/zh-CN/api-reference/rtc/macos/publishnsubscribe#api_irtcengine_setdualstreammode)，并在接收端申请接收小流以降低带宽消耗。
  - 接收端开启[视频流回退功能](/zh-CN/api-reference/rtc/macos/network#api_irtcengine_setremotesubscribefallbackoption)。

### 示例项目 [#示例项目-2]

声网提供了开源的示例项目供你参考，你可以前往下载或查看其中的源代码。

<Cards>
  <Card title="PrecallTest.swift" href="https://github.com/Shengwang-Community/API-Examples/blob/main/macOS/APIExample/Examples/Advanced/PrecallTest/PrecallTest.swift" />
</Cards>

### API 参考 [#api-参考-2]

- [`startEchoTestWithConfig`](/zh-CN/api-reference/rtc/macos/network#api_irtcengine_startechotest3)
- [`stopEchoTest`](/zh-CN/api-reference/rtc/macos/network#api_irtcengine_stopechotest)
- [`startLastmileProbeTest`](/zh-CN/api-reference/rtc/macos/network#api_irtcengine_startlastmileprobetest)
- [`stopLastmileProbeTest`](/zh-CN/api-reference/rtc/macos/network#api_irtcengine_stoplastmileprobetest)
- [`onLastmileQuality`](/zh-CN/api-reference/rtc/macos/network#callback_irtcengineeventhandler_onlastmilequality)
- [`onLastmileProbeResult`](/zh-CN/api-reference/rtc/macos/network#callback_irtcengineeventhandler_onlastmileproberesult)

### 相关文档 [#相关文档-2]

- [实现音视频互动](/zh-CN/realtime-media/rtc/get-started/quick-start)
- [设置视频编码属性](/zh-CN/realtime-media/rtc/build/video/video-profile)
- [设置音频编码属性](/zh-CN/realtime-media/rtc/build/audio/audio-profile)
















