如何基于ZEGO SDK 实现通话质量监测
如何基于ZEGO SDK 实现通话质量监测
1 功能简介
在进行视频通话过程中,用户有时候会出现网络不好的情况,比如在进行多人视频通话或者多人唱歌时,我们需要实时显示用户的网络质量。

示例源码
请参考 下载示例源码 获取源码。
相关源码请查看 “/ZegoExpressExample/Examples/AdvancedStreaming/StreamMonitoring” 目录下的文件。
前提条件
在监测通话质量之前,请确保:
- 已在项目中集成 ZEGO Express SDK,实现基本的实时音视频功能,详情请参考 快速开始 - 集成 和 快速开始 - 实现流程。
- 已在 ZEGO 控制台 创建项目,并申请有效的 AppID,详情请参考 控制台 - 项目管理 中的“项目信息”。
基础网络质量报告
可以通过监听 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开发者帐号,快速开始。
如何基于ZEGO SDK 实现通话质量监测的更多相关文章
- 如何基于 ZEGO SDK 实现 Windows 一对一音视频聊天应用
互联网发展至今,实时视频和语音通话越来越被大众所依赖. 今天,我们将会继续介绍如何基于ZEGO SDK实现音视频通话功能,前两篇文章分别介绍了Android,Flutter平台的实现方式,感兴趣的小伙 ...
- 如何基于 ZEGO SDK 实现 Flutter 一对一音视频聊天应用?
之前的文章发布了ZEGO SDK实现Android端音视频通话应用的开发教程,不少开发者反馈很实用,能不能也出一版Flutter的教程. 有求必应,这不小编来了- 我们封装了ZEGO Flutter ...
- 如何基于 ZEGO SDK 实现 Android 一对一音视频聊天应用
疫情期间,很多线下活动转为线上举行,实时音视频的需求剧增,在视频会议,在线教育,电商购物等众多场景成了"生活新常态". 本文将教你如何通过即构ZEGO sdk在Android端搭建 ...
- 如何基于 ZEGO SDK 实现 Android 通话质量监测
功能简介 在进行视频通话过程中,用户有时候会出现网络不好的情况,比如在进行多人视频通话或者多人唱歌时,我们需要实时显示用户的网络质量. 示例源码 参考 下载示例源码 获取源码. 相关源码请查看 &qu ...
- 用C/C++开发基于VLC SDK的视频播放器
在windows系统如果开发万能播放器,一般都是基本DirectShow来开发,开发也很简单,但缺点也很多,一个文件格式是否能够播放完全取决于你 是否安装了正确的解析器和解码器,即使现在有了万能解器安 ...
- 基于Win32 SDK实现的一个简易线程池
利用C++实现了一个简易的线程池模型(基于Win32 SDK),方便使用多线程处理任务.共包含Thread.h.Thread.cpp.ThreadPool.h.ThreadPool.cpp四个源文件. ...
- pyDash:一个基于 web 的 Linux 性能监测工具
pyDash 是一个轻量且基于 web 的 Linux 性能监测工具,它是用 Python 和 Django 加上 Chart.js 来写的.经测试,在下面这些主流 Linux 发行版上可运行:Cen ...
- 如何基于App SDK快速地开发一个IoT App?
一.背景及大纲介绍 在如今物联网DCM(Device.Connect.Manage)的大框架下,有一个应用层来分析和处理数据,是必备技能.但是,对于一个公司来说,因为研发能力或者研发时间的原因,可能很 ...
- 基于FBX SDK的FBX模型解析与加载 -(一)
http://blog.csdn.net/bugrunner/article/details/7210511 1. 简介 FBX是Autodesk的一个用于跨平台的免费三维数据交换的格式(最早不是由A ...
随机推荐
- Redis集群节点扩容及其 Redis 哈希槽
Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value 时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求 ...
- 请说说Struts1和Struts2的区别?
特性 Struts1 Struts2 Action Struts1.x要求Action类要扩展自一个抽象基类.Struts1.x的一个共有的问题是面向抽象类编程而不是面向接口编程. Struts2 ...
- zookeeper有几种部署模式? zookeeper 怎么保证主从节点的状态同步?
一.zookeeper的三种部署模式 Zookeeper 有三种部署模式分别是单机模式.伪集群模式.集群模式.这三种模式在不同的场景下使用: 单机部署:一般用来检验 Zookeeper 基础功能,熟悉 ...
- 解释AOP模块 ?
AOP模块用于发给我们的Spring应用做面向切面的开发, 很多支持由AOP联盟提供,这样就确保了Spring和其他AOP框架的共通性.这个模块将元数据编程引入Spring.
- Java 中的编译期常量是什么?使用它又什么风险?
公共静态不可变(public static final )变量也就是我们所说的编译期常量,这里 的 public 可选的.实际上这些变量在编译时会被替换掉,因为编译器知道这些 变量的值,并且知道这些变 ...
- 《手把手教你》系列基础篇(八十四)-java+ selenium自动化测试-框架设计基础-TestNG日志-上篇(详解教程)
1.简介 TestNG还为我们提供了测试的记录功能-日志.例如,在运行测试用例期间,用户希望在控制台中记录一些信息.信息可以是任何细节取决于目的.牢记我们正在使用Selenium进行测试,我们需要有助 ...
- html 5 读取本地文件API
代码: <input type="file" name="uploadfile" class="J-upload"> <s ...
- web入门+书籍推荐
如果你想建立一个自己的网站,你可以从网上搜到许多的教程:比如 wordpress gitpages 等等. 如果你想了解这个框架是怎么工作的,你可以了解以下下面的三个基本概念: 服务器, 数据库, 前 ...
- PAT B1081 检查密码
题目描述: 本题要求你帮助某网站的用户注册模块写一个密码合法性检查的小功能.该网站要求用户设置的密码必须由不少于6个字符组成,并且只能有英文字母.数字和小数点 .,还必须既有字母也有数字. 输入格式: ...
- 微信小程序获取当前时间戳、获取当前时间、时间戳加减
//获取当前时间戳 var timestamp = Date.parse(new Date()); timestamp = timestamp / 1000; console.log("当前 ...