通话前设备检测和网络质量探测
更新时间: 2024/08/05 15:02:55
在网络会议、重要直播等对音视频通话质量等要求较高的场景下,需要在通话前进行调试,例如可以进行设备检测以提前做好设备管理,或者探测网络质量以提前识别网络问题。NERTC SDK 提供通话前设备检测和网络探测的相关接口与回调方法,帮助您保证高质量的音视频通话体验。
功能介绍
通过创建 upClient
实例和对应的本地音视频流,以检测麦克风、摄像头、扬声器等设备的表现是否正常;此外也可以通过创建 upClient
和 downClient
两个实例,分别模拟上/下行用户进入虚拟房间进行推拉流,以检测上行和下行网络质量,并最终判断当前网络环境的平均质量。
API 调用时序
设备检测
在您的浏览器页面进行相关检测前,请先在该页面引入 NERTC Web SDK,具体请参考集成 SDK。
实现方法
-
调用
createStream
方法创建client
实例。示例代码如下:
let upClient=null; let downClient=null; let localStream=null; let remoteStream=null; let audioDevices=null; let videoDevices=null; let audioOutDevices=null; let intervalA=null; let intervalB=null; upClient = NERTC.createClient({ appkey: '', //您的 appkey debug: true, //是否开启调试日志 });
-
调用
getDevices
方法获取本地麦克风、摄像头和扬声器设备列表。示例代码如下:
function deviceInit(){ //确认浏览器是否符合要求 if (!NERTC.checkSystemRequirements()) { alert("browser is no support webRTC"); } NERTC.getDevices().then(function(devices){ audioDevices = devices.audioIn; //数组,麦克风设备列表,包含deviceId和label信息,网页上展示设备label信息供用户选择,实际测试时传入deviceId来打开设备确认设备是否可用 videoDevices = devices.video; //摄像头设备列表 audioOutDevices = devices.audioOut; //扬声器列表 console.log(audioDevices[0].deviceId, videoDevices[0].deviceId); }).catch(function(err){ console.warn(err); }) }
-
因浏览器的安全隐私政策,若您使用的是 Chrome(81+)、Safari 或 Firefox 浏览器,则需要在获取媒体设备权限后才能获取设备 ID。
-
设备 ID 为随机生成,部分情况下同一个设备的 ID 可能会改变,因此建议您在每次测试设备时均先调用
getDevices
方法获取最新的设备 ID。
-
-
打开对应的设备以确认设备是否可以正常使用。
-
创建音频流,获取音频流音量,以检测麦克风表现是否正常。
示例代码如下:
function streamCreate(){ //监听设备相关异常 upClient.on("accessDenied",function(evt){ console.log("accessDenied"+JSON.stringify(evt)); }) upClient.on("notFound",function(evt){ console.log("notFound"+JSON.stringify(evt)); }) upClient.on("deviceError",function(evt){ console.log("deviceError"+JSON.stringify(evt)); }) upClient.on("beOccupied",function(evt){ console.log("beOccupied"+JSON.stringify(evt)); }) localStream = NERTC.createStream({ uid: 112211,//传入随机字符串即可 audio: true, microphoneId: audioDevices[0].deviceId, //指定要开启的mic,填入获取到的deviceId video: false, }); //init失败时,会通过upClient上的accessDenied、notFound、deviceError、beOccupied这几个监听事件通知 localStream.init().then(function(){ intervalA=setInterval(function(){ console.log("获取mic采集的音量:"+localStream.getAudioLevel());//音量范围是0~1,大于0.1就表示音量比较正常 //在UI层动态展示获取到的音量,让终端用户确认音量条是否变化 }, 2000); localStream.play(document.getElementById("NE_local"),{audio:true})//此步骤可选,仅当需要直接播放采集到的声音时使用
请先创建纯音频流,确保麦克风设备正常之后再检测摄像头,以避免同时创建音视频流时检测两个设备造成的干扰。
-
打开摄像头,以检测摄像头表现是否正常。
示例代码如下:
//用于播放音视频的div元素 let createDivL=document.createElement("div"); createDivL.id="NE_local"; createDivL.style.width='640px'; createDivL.style.height='480px'; document.body.appendChild(createDivL) let divL = document.getElementById('NE_local') //开启摄像头 localStream.open({deviceId: videoDevices[0].deviceId,type:'video'}).then(function(){ console.log("摄像头打开成功");//打开成功后才能去做切换、关闭摄像头的操作 localStream.play(divL, { audio:false,video: true}).then((evt)=>{ console.log("播放成功");//把视频画面渲染到页面上,让用户确认视频画面内容是否正常 }).catch((evt)=>{ console.log(evt); }); localStream.setLocalRenderMode({ width: 640, height: 480, cut: false }) });
-
打开扬声器,以检测扬声器表现是否正常。
示例代码如下:
document.getElementById("audio").setSinkId(audioOutDevices[0].deviceId).then(function() { ... })
若您需要切换设备,如将麦克风切换为摄像头,可以直接调用
switchDevice
方法来实现。示例代码如下:
function switchDevice(){ //UI上展示设备名称,用户选择设备名称之后拿到对应的设备deviceId来进行切换操作 localStream.switchDevice("video", deviceId).then(function(){ console.log('设备切换成功'); }).catch(function(err){ console.log(err) }) }
-
网络探测
在您的浏览器页面进行相关检测前,请先在该页面引入 NERTC Web SDK,具体请参考集成 SDK。
实现方法
-
upClient
加入房间并推流。具体网络质量数值说明请参考
network-quality
。示例代码如下:
function upClientPub(){ //监听用户实际网络质量 upClient.on("network-quality",function(evt){ console.log("network-quality"+JSON.stringify(evt));//检测用户上行的网络质量 }) upClient.join({ channelName: "TEST",//RTC房间名 uid: 112211, token: "" //调试模式下传空即可 }).then(function () { console.log('upClient加入房间成功...' + uid);//此时表示用户TCP网络正常长链接建立成功 upClient.publish(localStream).then(function() { console.log('本地 publish 成功'); intervalB=setInterval(function(){ upClient.getTransportStats().then(function(stat){ console.log(stat); //获取本地网络上行预估带宽、RTT,根据这个结果判断用户UDP网络状态 }) }, 2000); }).catch(function(err){ console.warn(err) }); }).catch(function (err) { console.log(err); }); }
-
downClient
加入房间并拉流。具体网络质量数值说明请参考
network-quality
。示例代码如下:
function downClientSub(){ downClient= NERTC.createClient({ appkey: '', //您的 App key debug: true, //是否开启调试日志 }); downClient.on("network-quality",function(evt){ console.log("network-quality"+JSON.stringify(evt));//检测用户下行的网络质量 }) downClient.join({ channelName: "TEST",//RTC房间名 uid:112233, //随机用户Id token: "" //调试模式下传空即可 }).then(function () { console.log('接收方加入房间成功...' + uid); }).catch(function (err) { console.log(err); }); //回调事件-远端用户已发流 downClient.on('stream-added', function (evt) { console.log("远端有流来: " + evt.mediaType); remoteStream =evt.stream; remoteStream.setSubscribeConfig({ audio: true, video: true }); downClient.subscribe(remoteStream, function(){ console.log("Subscribe stream success"); },function (err) { console.log("Subscribe stream failed", err); }); }); //回调事件-远程音视频流已订阅 downClient.on('stream-subscribed', function (evt) { console.log('订阅远端流成功'); //渲染订阅到的视频流(可选) let createDivR=document.createElement("div"); createDivR.id="NE_remote"; createDivR.style.width='640px'; createDivR.style.height='480px'; document.body.appendChild(createDivR) let divRemote = document.getElementById('NE_remote'); evt.stream.play(divRemote,{audio:true,video:true}).then(() => { console.log('播放对端视频流成功'); }) evt.stream.setRemoteRenderMode({ width: 640, height: 480, cut: false //是否裁剪 },'video'); }) }
- 您可以选择不渲染订阅的视频流,只通过
network-quality
判断下行网络的等级;但建议您将订阅的视频流渲染至画布上,以模拟较为真实的音视频通话过程,从而对当前网络状况得出更真实的判断,同时您可以调用getRemoteAudioStats
和getRemoteVideoStats
方法以获取更全面的统计数据。 - 建议将推拉流过程的时长设置为 20s 左右,以取平均网络质量数据,从而大致判断出上下行网络情况。
- 您可以选择不渲染订阅的视频流,只通过
network-quality
详细值说明
在注册 on("network-quality")
网络质量监听回调后,您可以通过回调中的数值判断当前的网络状况。具体说明如下表。
数值 | 网络质量水平 | 说明 |
---|---|---|
0 | UNKNOWN | 网络状况未知,表示当前 client 实例还没有成功建立上行/下行连接 |
1 | EXCELLENT | 网络状况极佳 |
2 | GOOD | 网络状况较 |
3 | POOR | 网络状况一般 |
4 | BAD | 网络状况差 |
5 | VERYBAD | 网络状况极差 |
6 | DOWN | 网络连接已断开) |
建议当 network-quality
的数值大于 3 时,您可以检查网络并尝试更换网络环境,以保证正常的音视频通话。您也可以通过降低分辨率/帧率来降低带宽消耗,减少数据传输压力。