通话中质量监测

更新时间: 2024/03/15 17:25:02

在通话场景中,开发者经常需要了解当前通话的通话质量、设备状态等信息,监测通话的整体体验;也可将部分质量数据在 UI 层面展示给用户,使用户能够及时了解当前通话的整体质量。NERTC SDK 支持将关键的音视频状况、网络状况、设备状态的相关指标实时回调给 APP 应用层,应用层可以将收到的数据进行展示或统计。

例如,在进行多人连麦时,您可以展示用户的实时网络质量,如下图所示。

文本

功能介绍

NERTC SDK 提供注册质量监测观测器 NERtcStatsObserver 的接口与相关回调方法,支持在通话中实时同步并返回质量数据,包括上下行网络质量、本地通话统计信息、本地和远端的音视频流统计信息等。

示例项目

网易云信提供 MediaStats 示例项目源码,您可以参考该源码实现通话中质量监测。

实现方法

调用 setStatsObserver 方法注册质量观测器,主动设置相应回调,回调名称与返回的质量数据信息的对应关系如下表所示。

回调 统计信息
onNetworkQuality 上下行网络质量同步
onRtcStats 统计信息同步
onLocalAudioStatsonRemoteAudioStats 音频质量同步
onLocalVideoStatsonRemoteVideoStats 视频质量同步

若您需要关闭质量监测功能,再次调用此方法并传入 null 即可。

示例代码如下:

//返回本地通话统计信息
NERtcEx.getInstance().setStatsObserver(new NERtcStatsObserver() {
    @Override
    public void onRtcStats(NERtcStats stats) {
        String statsStrInfo = String.format(Locale.CHINA, "tx:%.2fMB rx: %.2fMB v_lost:%d%% a_lost:%d%% upRtt:%d downRtt:%d",
                stats.txBytes / M_SIZE, stats.rxBytes / M_SIZE,
                stats.txVideoPacketLossRate, stats.txAudioPacketLossRate, stats.upRtt, stats.downRtt);
    }

    //返回本地设备发送音频流的统计信息
    @Override
    public void onLocalAudioStats(NERtcAudioSendStats stats) {
        for (NERtcAudioLayerSendStats layer : stats.audioLayers) {
            // 音频主流及音频辅流
            String statsStrInfo = String.format(Locale.CHINA, "audio_type:%d , kbps:%dKbps vol:%d cap_vol:%d lost:%d%% rtt:%d",
                    layer.streamType, layer.kbps, layer.volume, layer.capVolume, layer.lossRate, layer.rtt);
        }
    }

    //返回通话中每个远端用户音频流的统计信息
    @Override
    public void onRemoteAudioStats(NERtcAudioRecvStats[] statsArray) {
        if (statsArray == null) {
            return;
        }
        for (NERtcAudioRecvStats stats : statsArray) {
            for (NERtcAudioLayerRecvStats layer : stats.layers) {
                // 音频主流及音频辅流
                String statsStrInfo = String.format(Locale.CHINA, "audio_type:%d , kbps:%dKbps vol:%d lost:%d%%",
                        layer.streamType, layer.kbps, layer.volume, layer.lossRate);
            }
        }
    }


    //返回本地设备发送视频流的统计信息
    @Override
    public void onLocalVideoStats(NERtcVideoSendStats stats) {
        if (stats == null) {
            return;
        }

        for (NERtcVideoLayerSendStats sendStats : stats.videoLayers) {
            String statsStrInfo = String.format(Locale.CHINA, "video_type:%d cap_width:%d cap_height:%d send_width:%d send_height:%d  fps:%d enc_bitrate:%d kbps send_bitrate:%d kbps encoder:%s",
                    sendStats.layerType,
                    sendStats.capWidth,
                    sendStats.capHeight,
                    sendStats.width,
                    sendStats.height,
                    sendStats.encoderOutputFrameRate,
                    sendStats.encoderBitrate,
                    sendStats.sendBitrate,
                    sendStats.encoderName);
        }

    }

    //返回通话中每个远端用户视频流的统计信息
    @Override
    public void onRemoteVideoStats(NERtcVideoRecvStats[] statsArray) {
        if (statsArray == null) {
            return;
        }
        for (NERtcVideoRecvStats stats : statsArray) {
            for (NERtcVideoLayerRecvStats recvStats : stats.layers) {
                String statsStrInfo = String.format(Locale.CHINA, "video_type%d: width:%d height:%d fps:%d bitrate:%d kbps lost:%d%% decoder:%s",
                        recvStats.layerType,
                        recvStats.width,
                        recvStats.height,
                        recvStats.fps,
                        recvStats.receivedBitrate,
                        recvStats.packetLossRate,
                        recvStats.decoderName);
            }
        }
    }


    //返回通话中每个成员的上下行网络质量
    @Override
    public void onNetworkQuality(NERtcNetworkQualityInfo[] statsArray) {
        if (statsArray == null) {
            return;
        }
        for (NERtcNetworkQualityInfo info : statsArray) {
            String statsStrInfo = String.format(Locale.CHINA, "uid:%d up:%d down:%d", info.upStatus, info.upStatus, info.downStatus);
        }

    }
});

相关回调的详细说明

上下行网络质量同步

onNetworkQuality 回调以数组的形式向您同步当前通话中每个成员的上下行网络质量。

  • 上行网络质量打分基于实际发送码率、上行网络丢包率、平均往返时延和上行网络抖动计算。
  • 下行网络质量打分基于下行网络丢包率、平均往返时延和下行网络抖动计算。
  • 每隔 2 秒您会收到房间内所有用户的网络质量同步。
  • 实际发送码率与目标发送码率的比值越高,该网络下的通话质量越好,该网络质量打分越高。

NERtcNetworkQualityInfo 数组中各参数的说明如下表所示。

参数 参数说明
userId 用户 ID,指定是哪个用户的网络质量统计。
upStatus 该用户的上行网络质量。
downStatus 该用户的下行网络质量。

其中网络质量以网络状态的好坏衡量,NetworkStatus 的各枚举值如下表所示。

枚举值 说明
UNKNOWN(0) 当前网络状态未知。
EXCELLENT(1) 当前网络状态极好。
GOOD(2) 当前网络状态不错。
POOR(3) 当前网络状态一般。
BAD(4) 当前网络状态比较差,可能出现卡顿和网络延迟。
VERYBAD(5) 当前网络状态非常差,无法保证正常的通话质量。
DOWN(6) 当前无网络。

统计信息同步

onRtcStats 回调向您同步本地通话统计信息。其中包含通话时长、当前通话房间中的人数、当前系统的 CPU 使用率、当前 App 的 CPU 使用率等重要数据。

参数 参数说明
cpuAppUsage、cpuTotalUsage App 的 CPU 使用率和系统的 CPU 使用率。
memoryAppUsageRatio、memoryAppUsageInKBytes、memoryTotalUsageRatio App 的内存使用率、内存使用量、系统的内存使用率。
totalDuration 通话总时长,单位为秒。
txBytes/rxBytes 累计发送/接收字节数。
txAudioBytes/rxAudioBytes 音频发送/接收字节数。
txVideoBytes/rxVideoBytes 视频发送/接收字节数。
txAudioKBitRate/rxAudioKBitRate 音频接收/发送码率,单位为 Kbps。
txVideoKBitRate/rxVideoKBitRate 视频接收/发送码率,单位为 Kbps。
upRtt/downRtt 上行/下行平均往返时延,单位为毫秒。
txAudioPacketLossRate/rxAudioPacketLossRate 本地上行/下行音频实际丢包率。
txAudioPacketLossSum/rxAudioPacketLossSum 本地上行/下行音频实际丢包数。
txAudioJitter/rxAudioJitter 本地上行/下行音频抖动计算,单位为毫秒。
txVideoJitter/rxVideoJitter 本地上行/下行视频抖动计算,单位为毫秒。
txVideoPacketLossRate/rxVideoPacketLossRate 本地上行/下行视频实际丢包率。
txVideoPacketLossSum/rxVideoPacketLossSum 本地上行/下行视频实际丢包数。

音频质量同步

本地音频流统计信息同步

onLocalAudioStats 回调向您同步本地设备发送音频流的统计信息,包括当前通话声道数(单声道或双声道)、发送音频的采样率和发送音频的码率。SDK 会每隔 2 秒自动触发本回调。

参数 参数说明
numChannels 当前采集的声道数。
sentSampleRate 统计周期内本地上行音频采样率,单位为 Hz。
kbps 统计周期内发送码率的平均值,单位为 Kbps。
lossRate 特定时间内的音频丢包率。
rtt 平均往返时延(RTT)。
volume 音量,取值范围为 0 ~ 100。

远端音频流统计信息同步

onRemoteAudioStats 回调向您同步当前通话中每个远端用户音频流的统计信息,包括每个远端用户发送的音频流质量、声道数等信息。SDK 会每隔 2 秒自动触发本回调。

参数 参数说明
uid 用户 ID,指定是哪个用户的音频流。
kbps 统计周期内接收到的码率平均值,单位为 Kbps。
totalFrozenTime 远端用户在加入房间后发生音频卡顿的累计时长,单位为毫秒。一个统计周期内,音频丢帧率达到 4% 即记为一次音频卡顿。
frozenRate 远端用户下行音频平均卡顿率。其值为远端用户在加入房间后发生音频卡顿的累计时长占音频总有效时长的百分比。
lossRate 统计周期内的远端音频流的丢帧率。
volume 音量,取值范围为 0 ~ 100。

视频质量同步

本地视频流统计信息同步

onLocalVideoStats 回调向您同步本地设备发送视频流的统计信息,包括视频编码宽/高等信息。SDK 会每隔 2 秒自动触发本回调。

如果您此前调用 enableDualStreamMode 方法开启了双流模式,则本回调描述本地设备发送的视频大流的统计信息。

参数 参数说明
layerType 视频流通道类型。
  • 1:主流。
  • 2:辅流。
  • width 视频编码宽度,单位为 px。
    height 视频编码高度,单位为 px。
    captureFrameRate 视频采集帧率,单位为 fps。
    renderFrameRate 视频渲染帧率,单位为 fps。
    encoderOutputFrameRate 编码帧率,单位为 fps。
    sentFrameRate 实际发送帧率,单位为 fps,不包含丢包后重传视频等的发送帧率。
    sendBitrate 实际发送码率,单位为 Kbps,不包含丢包后重传视频等的发送码率。
    targetBitrate 当前编码器的目标编码码率,单位为 Kbps,该码率为 SDK 根据当前网络状况预估的一个值。
    encoderBitrate 编码器实际编码码率,单位为 Kbps。
    encoderName 视频编码器的名称。

    远端视频流统计信息同步

    onRemoteVideoStats 回调向您同步当前通话中每个远端用户/主播的视频流的统计信息,包括每个远端用户的视频宽/高等参数信息。SDK 会每隔 2 秒自动触发本回调。

    参数 参数说明
    layerType 视频流通道类型。
  • 1:主流。
  • 2:辅流。
  • width 远端视频编码宽度,单位为 px。
    height 远端视频编码高度,单位为 px。
    receivedBitrate 接收到的码率,单位为 Kbps。
    fps 接收到的帧率,单位为 fps。
    decoderOutputFrameRate 解码帧率,单位为 fps。
    rendererOutputFrameRate 渲染帧率,单位为 fps。
    packetLossRate 远端视频下行丢包率。
    totalFrozenTime 远端用户加入房间后,其下行视频卡顿累计时长,单位为毫秒。
    frozenRate 远端用户加入房间后,其下行视频平均卡顿率,其值为视频卡顿的累计时长占视频总有效时长的百分比。
    decoderName 视频编码器的名称。
    此文档是否对你有帮助?
    有帮助
    去反馈
    • 功能介绍
    • 示例项目
    • 实现方法
    • 相关回调的详细说明
    • 上下行网络质量同步
    • 统计信息同步
    • 音频质量同步
    • 视频质量同步