如何基于ZEGO SDK 实现通话质量监测


1 功能简介

在进行视频通话过程中,用户有时候会出现网络不好的情况,比如在进行多人视频通话或者多人唱歌时,我们需要实时显示用户的网络质量。

示例源码

请参考 下载示例源码 获取源码。

相关源码请查看 “/ZegoExpressExample/Examples/AdvancedStreaming/StreamMonitoring” 目录下的文件。

前提条件

在监测通话质量之前,请确保:

基础网络质量报告

可以通过监听 onNetworkQuality 回调,收到房间内用户(包括自己)的上下行网络质量。此回调每隔两秒会收到一次,网络质量等级请参考 ZegoStreamQualityLevel

onNetworkQuality 回调的逻辑为:

  • 只要推流或者拉流,就能收到自己的网络质量回调。
  • 当拉取了其他用户推送的音视频流并且该用户在房间内时,才会收到该用户的网络质量回调。
  • 当 “userID” 为 “nil” 时,代表本次是自己的网络质量,当 “userID” 不为 “nil” 时,代表是房间内其他用户的报告。
- (void)onNetworkQuality:(NSString *)userID upstreamQuality:(ZegoStreamQualityLevel)upstreamQuality downstreamQuality:(ZegoStreamQualityLevel)downstreamQuality {
if (userID == nil) {
// 代表本地用户(我)的网络质量
NSLog(@"我的上行网络质量是 %lu", (unsigned long)upstreamQuality);
NSLog(@"我的下行网络质量是 %lu", (unsigned long)downstreamQuality);
} else {
//代表房间内其他用户的网络质量
NSLog(@"用户 %@ 的上行网络质量是 %lu", userID, (unsigned long)upstreamQuality);
NSLog(@"用户 %@ 的下行网络质量是 %lu", userID, (unsigned long)downstreamQuality);
} /*
ZegoStreamQualityLevelExcellent 网络质量极好
ZegoStreamQualityLevelGood 网络质量好
ZegoStreamQualityLevelMedium 网络质量正常
ZegoStreamQualityLevelBad 网络质量差
ZegoStreamQualityLevelDie 网络异常
ZegoStreamQualityLevelUnknown 网络质量未知
*/
}

进阶质量报告

如果上述的基础网络质量报告不能满足需求,ZEGO SDK 还提供了更详细的推流质量报告、拉流质量报告以及其他相关信息。

推流质量报告

推流质量报告指用户把音视频推送到 ZEGO 服务端这个过程的质量报告,包含了采集、编码阶段音视频流的帧率,传输(发送)的音视频流的帧率、码率、延时及丢包率。

可以通过注册 onPublisherQualityUpdate 接收推流质量回调,推流成功后每隔三秒会收到此回调。可根据 quality(ZegoPublishStreamQuality) 参数实时了解推送的音视频流的健康情况。

  • 大多数情况下,只需要关注 “quality” 的 “level” 参数,以 “level” 枚举值来判断推流的综合质量,详情可参考 ZegoStreamQualityLevel
  • 如果想关注更详细的推流质量参数,可以参考 ZegoPublishStreamQuality
    // 可以在此回调中监控具体的质量以上报到业务服务器做监控,或者监控质量对象的某个字段以给用户友好的提示
- (void)onPublisherQualityUpdate:(ZegoPublishStreamQuality *)quality streamID:(NSString *)streamID {
NSString *networkQuality = @"";
// level 代表了推流质量的综合分数,大部分情况下,可以参考此分数展示上行网络的质量 switch (quality.level) {
case ZegoStreamQualityLevelExcellent:
networkQuality = @"非常好";
break;
case ZegoStreamQualityLevelGood:
networkQuality = @"好";
break;
case ZegoStreamQualityLevelMedium:
networkQuality = @"一般";
break;
case ZegoStreamQualityLevelBad:
networkQuality = @"差";
break;
case ZegoStreamQualityLevelDie:
networkQuality = @"失败";
break;
case ZegoStreamQualityLevelUnknown:
networkQuality = @"未知";
break;
default:
break;
}
NSLog(@"推流的网络质量是:%@", networkQuality); }

拉流质量报告

拉流质量报告指用户拉取播放音视频流这个过程的质量报告,包含了接收的音视频流的帧率、码率、延时和丢包率,解码阶段音视频流的帧率,以及渲染阶段的帧率、卡顿率、音视频整体质量。

可以通过注册 onPlayerQualityUpdate 接收拉流质量回调,拉流成功后每隔三秒会收到此回调。可根据 quality(ZegoPlayStreamQuality) 参数实时了解拉取的音视频流的健康情况。

  • 大多数情况下,只需关注 “quality” 的 “level” 参数,以 “level” 枚举值来判断拉流的综合质量,详情可参考 ZegoStreamQualityLevel
  • 如果想关注更详细的拉流质量参数,可以参考 ZegoPlayStreamQuality
    // 可以在此回调中监控具体的质量以上报到业务服务器做监控,或者监控质量对象的某个字段以给用户友好的提示
- (void)onPlayerQualityUpdate:(ZegoPlayStreamQuality *) quality streamID:(NSString *) streamID {
NSString *networkQuality = @"";
// level 代表了拉流质量的综合分数,大部分情况下,可以参考此分数展示下行网络的质量 switch (quality.level) {
case ZegoStreamQualityLevelExcellent:
networkQuality = @"非常好";
break;
case ZegoStreamQualityLevelGood:
networkQuality = @"好";
break;
case ZegoStreamQualityLevelMedium:
networkQuality = @"一般";
break;
case ZegoStreamQualityLevelBad:
networkQuality = @"差";
break;
case ZegoStreamQualityLevelDie:
networkQuality = @"失败";
break;
case ZegoStreamQualityLevelUnknown:
networkQuality = @"未知";
break;
default:
break;
}
NSLog(@"拉流的网络质量是:%@", networkQuality); }

MOS 音质评分

ZEGO Express SDK 2.16.0 版本开始,拉流质量回调 onPlayerQualityUpdate 中新增 "mos" 字段,表示对拉流音质的评分。对音频质量比较关注时,可通过该字段了解当前音频的质量情况。

mos 字段的取值范围为 [-1, 5],其中 -1 表示未知(例如异常拉流时无法评分),[0, 5] 表示评分。实时音频 MOS 评分对应的主观音质感受如下:

MOS 值 评价标准
4.0~5.0 音质很好,清晰流畅,听的清楚。
3.5~4.0 音质较好,偶有音质损伤,但依然清晰流畅,听的清楚。
3.0~3.5 音质一般,偶有卡顿,需要一点注意力才能听清。
2.5~3.0 音质较差,卡顿频繁,需要集中注意力才能听清。
2.0~2.5 音质很差,部分语义丢失,难以交流。
小于 2.0 音质极差,大量语义丢失,无法交流。
-1 未知。

其他信息监测

推流/拉流状态变化通知

1. 推流状态回调

在推流成功后,可通过 onPublisherStateUpdate 获取推流状态变更的通知。

- (void)onPublisherStateUpdate:(ZegoPublisherState)state errorCode:(int)errorCode extendedData:(NSDictionary *)extendedData streamID:(NSString *)streamID {
// 当 state 为 PUBLISHER_STATE_NO_PUBLISH 时,且 errcode 非 0,表示推流失败,同时不会再进行重试推流了,此时可在界面作出推流失败提示。
// 当 state 为 PUBLISHER_STATE_PUBLISH_REQUESTING 时,且 errcode 非 0,表示在重试推流,此时如果超出重试时间未成功推流会抛出推流失败通知。
}

可以根据回调内的 “state” 参数是否在 “正在请求推流状态” 来大体判断用户的推流网络情况。“state” 参数的取值与用户推流状态对应如下:

枚举值 说明
ZegoPublisherStateNoPublish 未推流状态,在推流前处于该状态。如果推流过程出现稳态的异常,例如 AppID 或 Token 不正确,或者如果其他用户已经在推送流,推送相同流 ID 的流会失败,都会进入未推流状态。
ZegoPublisherStatePublishRequesting 正在请求推流状态,推流操作执行成功后会进入正在请求推流状态,通常通过该状态进行 UI 界面的展示。如果因为网络质量不佳产生的中断,SDK 会进行内部重试,也会回到正在请求推流状态。
ZegoPublisherStatePublishing 正在推流状态,进入该状态表明推流已经成功,用户可以正常通信。

参数 “extendedData” 为状态更新附带的扩展信息。若使用 ZEGO 的 CDN 内容分发网络,在推流成功后,该参数的内容的键为 “flv_url_list”、“rtmp_url_list”、“hls_url_list”,分别对应 flv、rtmp、hls 协议的拉流 URL。

2. 拉流状态变更回调

在拉流成功后,可通过 onPlayerStateUpdate 获取推流状态变更的通知。

- (void)onPlayerStateUpdate:(ZegoPlayerState)state errorCode:(int)errorCode extendedData:(NSDictionary *)extendedData streamID:(NSString *)streamID {
// 当 state 为 PLAYER_STATE_NO_PLAY 时,且 errcode 非 0,表示拉流失败,同时不会再进行重试拉流了,此时可在界面作出拉流失败提示。
// 当 state 为 PLAYER_STATE_PLAY_REQUESTING 时,且 errcode 非 0,表示重试拉流,此时如果超出重试时间未成功拉到流会抛出拉流失败通知。
}

可根据 “state” 参数是否在 “正在请求拉流状态” 来大体判断用户的拉流网络情况。“state” 参数的取值与用户拉流状态对应如下:

枚举值 说明
ZegoPlayerStateNoPlay 未拉流状态,在拉流前处于该状态。如果拉流过程出现稳态的异常,例如 AppID 或 Token 不正确,都会进入未拉流状态。
ZegoPlayerStatePlayRequesting 正在请求拉流状态,拉流操作执行成功后会进入正在请求拉流状态,通常通过该状态进行应用界面的展示。如果因为网络质量不佳产生的中断,SDK 会进行内部重试,也会回到正在请求拉流状态。
ZegoPlayerStatePlaying 正在拉流状态,进入该状态表明拉流已经成功,用户可以正常通信。

接收到音频/视频首帧的通知

1. 推流端音频采集首帧回调

可以通过注册 onPublisherCapturedAudioFirstFrame 接收音频首帧回调。调用推流接口成功后,SDK 采集到第一帧音频数据时会收到此回调。

在未推流或未预览的情况下,首次推流或首次预览,即 SDK 内部的音视频模块的引擎启动时,会去采集本机设备的音频数据,会收到该回调。开发者可根据该回调判断 SDK 是否真的采集到音频数据,若未收到该回调,说明音频采集设备被占用或异常。

- (void)onPublisherCapturedAudioFirstFrame {

}

2. 推流端视频采集首帧回调

可以通过注册 onPublisherCapturedVideoFirstFrame 接收视频首帧回调。调用推流接口成功后,SDK 采集到第一帧视频数据时会收到此回调。

在未推流或未预览的情况下,首次推流或首次预览,即 SDK 内部的音视频模块的引擎启动时,会去采集本机设备的视频数据,会收到该回调。可以根据该回调判断 SDK 是否真的采集到视频数据,若未收到该回调,说明视频采集设备被占用或异常。

- (void)onPublisherCapturedVideoFirstFrame:(ZegoPublishChannel)channel {

}

3. 拉流端音频接收首帧回调

可以通过注册 onPlayerRecvAudioFirstFrame 监听拉流端音频接收首帧回调。调用拉流接口成功后,SDK 拉流拉到第一帧音频数据时会收到此回调。

- (void)onPlayerRecvAudioFirstFrame:(NSString *)streamID {
}

4. 拉流端视频接收首帧回调

可以通过注册 onPlayerRecvVideoFirstFrame 监听拉流端接收视频首帧回调。调用拉流接口成功后,SDK 拉流拉到第一帧视频数据时会收到此回调。

- (void)onPlayerRecvVideoFirstFrame:(NSString *)streamID {
}

5. 拉流端渲染完视频首帧回调

可以通过注册 onPlayerRenderVideoFirstFrame 监听拉流端渲染完视频首帧回调。调用拉流接口成功后,SDK 拉流并渲染完第一帧视频数据后会收到此回调。

可用该回调来统计首帧耗时或更新播放流的 UI 组件。

- (void)onPlayerRenderVideoFirstFrame:(NSString *)streamID
}

视频分辨率变化的回调

1. 采集视频分辨率变更回调

可以通过注册 onPublisherVideoSizeChanged 监听采集视频大小变更回调。推流成功后,在推流中途如果视频采集分辨率发生变化将会收到此回调。

当在未推流或未预览的情况下,首次推流或首次预览,即 SDK 内部的音视频模块的引擎启动时,会去采集本机设备的视频数据,此时采集分辨率会改变。

可以根据此回调来去除本地预览的 UI 的遮盖等类似操作。也可以根据该回调的分辨率来动态调整预览视图的比例等。

- (void)onPublisherCapturedVideoFirstFrame:(ZegoPublishChannel)channel {
}

2. 拉流分辨率变更通知

可以通过注册 onPlayerVideoSizeChanged 获取拉流分辨率变更通知。拉流成功后,在拉流中途如果有视频分辨率发生变化将会收到此回调,可根据流的最终分辨率调整显示。

  • 若拉的流只有音频数据,会收不到该回调。
  • 若推流端由于网络问题触发 SDK 内部的流量控制时,可能会动态减小推流端的编码分辨率,此时也会收到此回调。所拉的音视频流真正渲染到所设置 UI 播放界面时会触发此回调。可利用该回调通知来更新或切换真正播放流的 UI 组件。
- (void)onPublisherVideoSizeChanged:(CGSize)size channel:(ZegoPublishChannel)channel {
}

API 参考列表

方法 描述
onPublisherQualityUpdate 推流质量回调
onPlayerQualityUpdate 拉流质量更新回调
onPublisherStateUpdate 推流状态回调
onPlayerStateUpdate 拉流状态回调
onPublisherCapturedAudioFirstFrame 推流端音频采集首帧回调
onPublisherCapturedVideoFirstFrame 推流端视频采集首帧回调
onPlayerRecvAudioFirstFrame 拉流端音频接收首帧回调
onPlayerRecvVideoFirstFrame 拉流端视频接收首帧回调
onPlayerRenderVideoFirstFrame 拉流端渲染完视频首帧回调
onPublisherVideoSizeChanged 采集视频大小变更回调
onPlayerVideoSizeChanged 拉流分辨率变更通知
onPublisherRelayCDNStateUpdate 添加/删除转推 CDN 地址状态回调
onPlayerRecvSEI 收到远端流的 SEI 内容

获取更多文档、Demo、技术帮助

获取 SDK 开发文档、demo,可访问 即构文档中心.

获取更多商务活动热门产品,可提交 信息联系商务.

注册即构ZEGO开发者帐号,快速开始。

最新文章

  1. Toad各版本所包含的组件
  2. Kettle实现MapReduce之WordCount
  3. Python自动化之select、greenlet和gevent和事件驱动模型初探
  4. UVA 11527 Unique Snowflakes
  5. vsftpd2.3.2安装、配置详解
  6. hibernate 知识梳理
  7. Debian 6配置GNOME桌面环境
  8. Properties操作
  9. Java对象与Json之间的转换
  10. 在DLL动态链接库中封装VCL的MDI子窗体
  11. 深入浅出Node.js (1) - Node简介
  12. vim删除^M
  13. AWS-SS配置过程
  14. img标签的onerror事件
  15. h5 中软键盘弹出后,点击退出键盘,页面无法恢复
  16. 安卓开发_WebView如何在Fragment中使用
  17. 安卓开发----TextView控件属性列表(转)
  18. Docker 以 docker 方式运行 jenkins
  19. Support For C++11/14/17 Features (Modern C++)
  20. Lintcode455-StudentID-Easy

热门文章

  1. 实习项目1-串口IP升级调试
  2. 半吊子菜鸟学Web开发5 -- PHP开发环境配置
  3. JDK,JRE,JVM的作用及关系
  4. B树、B+树、B*树三者的对比详解
  5. SQL语句分为哪几种?
  6. Spring基于xml注入bean的几种方式?
  7. Mosquitto安装和使用
  8. ROS的安装-> rosdep init /update报错2022.02.24实测有效
  9. cpu设计过程
  10. 用css动态实现圆环百分比分配——初探css3动画