通话前设备检测和网络质量探测

更新时间: 2024/08/05 15:02:55

在网络会议、重要直播等对音视频通话质量等要求较高的场景下,需要在通话前进行调试,例如可以进行设备检测以提前做好设备管理,或者探测网络质量以提前识别网络问题。NERTC SDK 提供通话前设备检测和网络探测的相关接口与回调方法,帮助您保证高质量的音视频通话体验。

功能介绍

通过创建 upClient 实例和对应的本地音视频流,以检测麦克风、摄像头、扬声器等设备的表现是否正常;此外也可以通过创建 upClient 和 downClient 两个实例,分别模拟上/下行用户进入虚拟房间进行推拉流,以检测上行和下行网络质量,并最终判断当前网络环境的平均质量。

API 调用时序

uml diagram

设备检测

在您的浏览器页面进行相关检测前,请先在该页面引入 NERTC Web SDK,具体请参考集成 SDK

实现方法

  1. 调用 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, //是否开启调试日志
    });
    
  2. 调用 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。

  3. 打开对应的设备以确认设备是否可以正常使用。

    1. 创建音频流,获取音频流音量,以检测麦克风表现是否正常。

      示例代码如下:

      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})//此步骤可选,仅当需要直接播放采集到的声音时使用
      

      请先创建纯音频流,确保麦克风设备正常之后再检测摄像头,以避免同时创建音视频流时检测两个设备造成的干扰。

    2. 打开摄像头,以检测摄像头表现是否正常。

      示例代码如下:

      //用于播放音视频的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
          })
      });
      
    3. 打开扬声器,以检测扬声器表现是否正常。

      示例代码如下:

      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

实现方法

  1. 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);
            });
    }
    
  2. 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 判断下行网络的等级;但建议您将订阅的视频流渲染至画布上,以模拟较为真实的音视频通话过程,从而对当前网络状况得出更真实的判断,同时您可以调用 getRemoteAudioStatsgetRemoteVideoStats 方法以获取更全面的统计数据。
    • 建议将推拉流过程的时长设置为 20s 左右,以取平均网络质量数据,从而大致判断出上下行网络情况。

network-quality 详细值说明

在注册 on("network-quality") 网络质量监听回调后,您可以通过回调中的数值判断当前的网络状况。具体说明如下表。

数值 网络质量水平 说明
0 UNKNOWN 网络状况未知,表示当前 client 实例还没有成功建立上行/下行连接
1 EXCELLENT 网络状况极佳
2 GOOD 网络状况较
3 POOR 网络状况一般
4 BAD 网络状况差
5 VERYBAD 网络状况极差
6 DOWN 网络连接已断开)

建议当 network-quality 的数值大于 3 时,您可以检查网络并尝试更换网络环境,以保证正常的音视频通话。您也可以通过降低分辨率/帧率来降低带宽消耗,减少数据传输压力。

此文档是否对你有帮助?
有帮助
去反馈
  • 功能介绍
  • API 调用时序
  • 设备检测
  • 实现方法
  • 网络探测
  • 实现方法
  • network-quality 详细值说明