0


WebRTC接收端动态控制jitterBufferTarget

新版本的WebRTC支持在已经建立连接的情况下,接收端支持动态调整自己的jitterBufferTarget。在Chrome124版本中可以体验这个功能了。通过两个网页进行webrtc通信,具体效果见下面的视频。

什么是jitterBuffer

jitterBuffer是抖动缓冲器。简单的理解就是缓冲器越大,网络抖动的时候越不容易卡顿、延迟越大。反之缓冲器越小,网络抖动的时候越容易卡顿、延迟越低。

效果

在这里插入图片描述

上面的视频使用chrome 124(目前是chrome的beta版本)进行演示。使用nodejs创建了一个websocket server的服务,用来交换两个页面的offer和answer。具体可以参考:前端使用WebRTC———局域网内单向通信。

  1. 通过拉流页面中的输入框可以设置jitterBufferTarget。可以在chrome://webrtc-internals中可以看到设置的参数是可以动态生效的。
  2. 在视频的后半段,推流端使用了一个视频,订阅端将jitterBufferTarget设置为2000毫秒,来演示接收端的延迟效果。可以看到视频中每秒会增加一个小圆圈,设置为2000毫秒的jitterBufferTarget后,拉流端的视频中的小圆圈和推流视频中小圆圈一直保持2个的差距。表示设置是生效的。

实现方法

核心代码

拉流端通过RTCRtpReceiver.jitterBufferTarget方法,可以支持动态调整jitterBufferTarget的大小(最大4000ms)。

const receivers = pc_sub.getReceivers();if(arr.length >0){// demo多次刷新会复用同一个pc,导致存在多个receiver,所以此处用最后一个const receiver = arr[arr.length-1];// 兼容性判断,低版本浏览器不支持此方法if(receiver.jitterBufferTarget !==undefined){
    receiver.jitterBufferTarget = jitterBufferTarget;}}

实际应用

在使用WebRTC进行通信时,不同的业务场景,我们对于延迟和卡顿有不同的需求,比如在网络好的情况下,我们希望延迟尽可能的小一些,就可以将jitterBufferTarget的延迟设置的比较小,反之用户的网络不好的情况下,就把jitterBufferTarget的延迟设置的大一些,尽量减少卡顿。或者在云游戏的场景,也可以尽可能的减小jitterBufferTarget来减小端到端延迟,获得更好的游戏体验。

代码

可以直接从gittee获取源代码,也可以直接使用下面的代码

服务端

要注意server依赖了nodejs-websocket模块。

var ws =require("nodejs-websocket");var pub_ws =null;var sub_ws =null;functionstart(){var msg =JSON.stringify({type:"start"});
  pub_ws.send(msg);}var server = ws.createServer(function(conn){// 收到websocket连接
  conn.on("text",function(str){if(pub_ws === conn){if(sub_ws){
        sub_ws.send(str);}}elseif(sub_ws === conn){if(pub_ws){
        pub_ws.send(str);}}else{let obj =JSON.parse(str);if(obj.type ==='publish'){
        pub_ws = conn;if(sub_ws){start();}}elseif(obj.type ==='subscribe'){
        sub_ws = conn;if(pub_ws){start();}}}})

  conn.on("error",function(event){});

  conn.on("close",function(code, reason){if(conn === pub_ws){
      console.log("remove pub")
      pub_ws =null;}elseif(conn === sub_ws){
      console.log("remove sub")
      sub_ws =null;}})}).listen(9000);
推流端

推流页面需要用localhost访问,因为获取设备需要https或者localhost(127.0.0.1)才可以。获取设备部分可以参考# 获取浏览器麦克风、摄像头和屏幕共享其中websoket server的ip写的是127.0.0.1,可以自行改成websocket server的局域网ip地址。

<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><title>推流页面</title></head><body><video id="localStream" style="width: 320px; height: 240px;" autoplay muted></video><script>// 获取摄像头返回的MediaStreamlet localStream =null;// 显示本地画面的VideoElementlet localVideo = document.getElementById("localStream");// 推流用的MediaStreamlet pc_pub =newRTCPeerConnection();let ws =newWebSocket('ws://127.0.0.1:9000');
      ws.addEventListener('open',()=>{// 通知server pub已经上线
        ws.send(JSON.stringify({type:"publish"}))})

      ws.addEventListener('message',(event)=>{let msg =JSON.parse(event.data);switch(msg.type){case"start":start();break;case"answer":
            pc_pub.setRemoteDescription(msg).then(()=>{}).catch((err)=>{})break;default:
            pc_pub.addIceCandidate(msg);break;}})

      pc_pub.addEventListener('icecandidate',(event)=>{if(event.candidate){
          ws.send(JSON.stringify(event.candidate));}})functionstart(){getDevice().then((mediaStream)=>{
          pc_pub.addTrack(mediaStream.getVideoTracks()[0], mediaStream);
          pc_pub.createOffer().then((offer)=>{
            pc_pub.setLocalDescription(offer).then(()=>{
              ws.send(JSON.stringify(offer));}).catch((err)=>{
              console.error('setLocalDescription error', err);})}).catch((err)=>{
            console.error("create offer error", err);})}).catch((err)=>{
          console.error("getDevice error", err);})}functiongetDevice(){returnnewPromise((resolve, reject)=>{
          navigator.mediaDevices.getUserMedia({video:true}).then((mediaStream)=>{
            localVideo.srcObject = mediaStream;resolve(mediaStream);}).catch((err)=>{reject(err);})})}</script></body></html>
订阅端

其中websoket server的ip写的是127.0.0.1,可以自行改成websocket server的局域网ip地址。

<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><title>拉流页面</title></head><body><video id="remoteStream" style="width: 320px; height: 240px;" autoplay muted></video><div>jitterBufferTarget:<input id="jitterBufferTarget_input"/><button id="jitterBufferTarget_button">设置</button></div><script>// 显示订阅视频的VideoElementlet remoteStream = document.getElementById("remoteStream");// 订阅流用的Peerconnectionlet pc_sub =newRTCPeerConnection();const jitterBufferTarget_button = document.getElementById("jitterBufferTarget_button");const jitterBufferTarget_input = document.getElementById("jitterBufferTarget_input");let ws =newWebSocket('ws://127.0.0.1:9000');
      ws.addEventListener('open',()=>{// 通知server pub已经上线
        ws.send(JSON.stringify({type:"subscribe"}))})

      ws.addEventListener('message',(event)=>{let msg =JSON.parse(event.data);switch(msg.type){case"start":break;case"offer":
            pc_sub.setRemoteDescription(msg).then(()=>{
              pc_sub.createAnswer().then((answer)=>{
                pc_sub.setLocalDescription(answer).then(()=>{
                  ws.send(JSON.stringify(answer));}).catch((err)=>{})}).catch((err)=>{
                console.error('create answer error', err);})}).catch((err)=>{
              console.error('setRemoteDescription error', err);})break;default:
            pc_sub.addIceCandidate(msg);break;}})

      pc_sub.addEventListener('icecandidate',(event)=>{if(event.candidate){
          ws.send(JSON.stringify(event.candidate));}})

      pc_sub.addEventListener('track',(event)=>{
        remoteStream.srcObject = event.streams[0];})

      jitterBufferTarget_button.addEventListener("click",()=>{const jitterBufferTarget =parseInt(jitterBufferTarget_input.value);if(jitterBufferTarget <0|| jitterBufferTarget >4000){return;}const receivers = pc_sub.getReceivers();if(arr.length >0){// demo多次刷新会复用同一个pc,导致存在多个receiver,所以此处用最后一个const receiver = arr[arr.length-1];// 兼容性判断,低版本浏览器不支持此方法if(receiver.jitterBufferTarget !==undefined){
            receiver.jitterBufferTarget = jitterBufferTarget;}}})</script></body></html>

其他

如果你也是专注前端多媒体或者对前端多媒体感兴趣,可以关注微信公众号“前端多媒体”


本文转载自: https://blog.csdn.net/fjqgx/article/details/137471340
版权归原作者 豆包啊啊 所有, 如有侵权,请联系我们删除。

“WebRTC接收端动态控制jitterBufferTarget”的评论:

还没有评论