在通话过程中,检测用户的网络质量,可以判断用户当下的网络质量情况。若用户网络质量太差,应建议用户检查网络或尝试更换网络,以保证正常通话质量。
本文主要介绍如何基于RoomCallback.connection_indicator事件实现通话过程网络质量检测。
通话过程中的网络质量检测
room.addCallback(RoomCallback.mcu_peerconnection_completed, onMCUPeerConnectionCompleted);
room.addCallback(RoomCallback.connection_indicator, onConnectionIndicator);
function onMCUPeerConnectionCompleted() {
var connectionInfoInterval = 1000; //网络情况收集计算频率
room.connectionInfoCollector.start(connectionInfoInterval); //开始收集网络情况,不填写频率参数,默认1000毫秒
room.connectionInfoCollector.stop(); //停止收集网络情况
}
/**
* 网络状态回调
*/
function onConnectionIndicator(connectionIndicator) {
if(connectionIndicator) {
var roomConnection = connectionIndicator.getRoomConnection();
if(roomConnection) {
var localAddress = "本地地址: " + roomConnection.localAddress;
var localPort = "本地端口: " + roomConnection.localPort;
var localProtocol = "本地协议: " + roomConnection.localProtocol;
var remoteAddress = "远端地址: " + roomConnection.remoteAddress;
var remotePort = "远端端口: " + roomConnection.remotePort;
var remoteProtocol = "远端协议: " + roomConnection.remoteProtocol;
var bitrate = "流量: 下行/" + roomConnection.downloadBitrate + ", 上行/" + roomConnection.uploadBitrate;
var packet = "数据包:下行/" + roomConnection.downloadPacket + ", 上行/" + roomConnection.uploadPacket;
var packetLost = "数据包丢包数: 下行/" + roomConnection.downloadPacketLost + ", 上行/" + roomConnection.uploadPacketLost;
var packetLossRate = "数据包丢包率: 下行/" + roomConnection.downloadPacketLostRate + ", 上行/" + roomConnection.uploadPacketLostRate;
var currentRoundTripTime = "当前的往返时间(RTT): " + roomConnection.currentRoundTripTime;
var totalRoundTripTime = "累计的往返时间(RTT): " + roomConnection.totalRoundTripTime;
}
}
}
结果分析
经过上述步骤,可以拿到上下行丢包率来评估网络质量。
另外也提供了回调接口来获取到音频流、视频流、桌面共享流的相关检测指标
room.addCallback(RoomCallback.mcu_peerconnection_completed, onMCUPeerConnectionCompleted);
room.addCallback(RoomCallback.connection_indicator, onConnectionIndicator);
function onMCUPeerConnectionCompleted() {
var connectionInfoInterval = 1000; //网络情况收集计算频率
room.connectionInfoCollector.start(connectionInfoInterval); //开始收集网络情况,不填写频率参数,默认1000毫秒
room.connectionInfoCollector.stop(); //停止收集网络情况
}
/**
* 音频流、视频流、桌面共享流的相关指标检测回调
*/
function onConnectionIndicator(connectionIndicator) {
if(connectionIndicator) {
var participants = room.getParticipants();
participants.forEach(function(user) {
//音频流相关
if(user && user.audio && (user.audio.status == 2 || user.audio.status == 3)){
var audioConnection = connectionIndicator.getAudioConnection(user.id);
if(audioConnection) {
var audioBitrate = "流量: 下行/" + audioConnection.downloadBitrate + ", 上行/" + audioConnection.uploadBitrate;
var audioPacket = "数据包: 下行/" + audioConnection.downloadPacket + ", 上行/" + audioConnection.uploadPacket;
var audioPacketLost = "数据包丢包数: "+ audioConnection.packetsLost;
var audioPacketLostRate = "数据包丢包率 : "+ audioConnection.packetLostRate;
var ssrc = "ssrc : " + audioConnection.ssrc;
var trackId = "trackId : " + audioConnection.trackId;
var payloadType = "payloadType : " + audioConnection.payloadType;
var mimeType = "mimeType : " + audioConnection.mimeType;;
var clockRate = "clockRate : " + audioConnection.clockRate;
}
}
//视频流相关
if(user && user.videos && user.videos.length>0){
for(var i=0; i<user.videos.length; i++){
var video = user.videos[i];
if(video.status == 2){
var videoConnection = connectionIndicator.getVideoConnection(user.id, video.id);
if(videoConnection) {
var videoBitrate = "流量: 下行/" + videoConnection.downloadBitrate + ", 上行/" + videoConnection.uploadBitrate;
var videoPacket = "数据包: 下行/" + videoConnection.downloadPacket + ", 上行/" + videoConnection.uploadPacket;
var videoPacketLost = "数据包丢包数 : "+ videoConnection.packetsLost;
var videoPacketLostRate = "数据包丢包率 : "+ videoConnection.packetLostRate;
var resolution = "分辨率 : " + videoConnection.resolution;
var frameRate = "帧率 : " + videoConnection.frameRate;
var qpSum = "媒体数据包的总量化值(qpSum) : " + videoConnection.qpSum;
var framesEncoded = "已编码帧的数量 : " + videoConnection.framesEncoded;
var framesDecoded = "已解码帧的数量 : " + videoConnection.framesDecoded;
var perFrameQP = "每个视频帧的平均量化值(perFrameQP) : " + videoConnection.perFrameQP;
var ssrc = "ssrc : " + videoConnection.ssrc;
var trackId = "trackId : " + videoConnection.trackId;
var payloadType = "payloadType : " + videoConnection.payloadType;
var mimeType = "mimeType : " + videoConnection.mimeType;
var clockRate = "clockRate : " + videoConnection.clockRate;
}
}
}
//桌面共享流相关
if(user && user.screen && user.screen.status == 2 ){
var screenConnection = connectionIndicator.getScreenConnection(user.id);
if(screenConnection) {
var screenBitrate = "流量 : <span class='jitsipopover_green'>↓</span>" + screenConnection.downloadBitrate + " <span class='jitsipopover_orange'>↑</span>" + screenConnection.uploadBitrate;
var screenPacket = "数据包 : <span class='jitsipopover_green'>↓</span>" + screenConnection.downloadPacket + " <span class='jitsipopover_orange'>↑</span>" + screenConnection.uploadPacket;
var screenPacketLost = "数据包丢包数 : "+ screenConnection.packetsLost;
var screenPacketLostRate = "数据包丢包率 : "+ screenConnection.packetLostRate;
var resolution = "分辨率 : " + screenConnection.resolution;
var frameRate = "帧率 : " + screenConnection.frameRate;
var ssrc = "ssrc : " + screenConnection.ssrc;
var trackId = "trackId : " + screenConnection.trackId;
var payloadType = "payloadType : " + screenConnection.payloadType;
var mimeType = "mimeType : " + screenConnection.mimeType;
var clockRate = "clockRate : " + screenConnection.clockRate;
}
}
}
}
}
}