【问题标题】:Unable to limit WebRTC P2P Multi-participant Receiving Bandwidth无法限制 WebRTC P2P 多方接收带宽
【发布时间】:2019-05-15 03:24:18
【问题描述】:

我正在尝试使用此示例结合我现有的多参与者视频通话代码来更改 WebRTC P2P 视频通话的动态带宽:

示例https://webrtc.github.io/samples/src/content/peerconnection/bandwidth/

当我通过 Chrome 查看 WebRTC 内部结构时,

bitsReceivedPerSecond 用于 send (ssrc) (video) 已下降到所选带宽。但是,recv (ssrc) (video)bitsReceivedPerSecond 仍然保持不变。我可以知道如何使带宽更改同时适用于发送和接收吗?

以下是我的代码,如果您能帮助指出我的错误,那就太好了,在此先感谢。

2018 年 14 月 12 日更新:在代码中添加了接收器的第一个选项

问题:未捕获的 TypeError:receiver.getParameters 不是函数

const bandwidthSelector = document.querySelector('select#bandwidth');

bandwidthSelector.disabled = false;

// renegotiate bandwidth on the fly.
bandwidthSelector.onchange = () => {
  bandwidthSelector.disabled = true;
  const bandwidth = bandwidthSelector.options[bandwidthSelector.selectedIndex].value;

  // In Chrome, use RTCRtpSender.setParameters to change bandwidth without
  // (local) renegotiation. Note that this will be within the envelope of
  // the initial maximum bandwidth negotiated via SDP.
  if ((adapter.browserDetails.browser === 'chrome' ||
       (adapter.browserDetails.browser === 'firefox' &&
        adapter.browserDetails.version >= 64)) &&
      'RTCRtpSender' in window &&
      'setParameters' in window.RTCRtpSender.prototype) {

        $.each(peers, function( index, value ) {
            const sender = value.getSenders()[0];
            const parameters = sender.getParameters();
            if (!parameters.encodings) {
              parameters.encodings = [{}];
            }
            if (bandwidth === 'unlimited') {
              delete parameters.encodings[0].maxBitrate;
            } else {
              parameters.encodings[0].maxBitrate = bandwidth * 1000;
            }
            sender.setParameters(parameters)
            .then(() => {
              bandwidthSelector.disabled = false;
            })
            .catch(e => console.error(e));

            /* 1st Option - Start */
            const receiver = value.getReceivers()[0];
            const recParameters = receiver.getParameters();

            if (!recParameters.encodings) {
              recParameters.encodings = [{}];
            }
            if (bandwidth === 'unlimited') {
              delete recParameters.encodings[0].maxBitrate;
            } else {
              recParameters.encodings[0].maxBitrate = bandwidth * 1000;
            }
            receiver.setParameters(recParameters)
            .then(() => {
              bandwidthSelector.disabled = false;
            })
            .catch(e => console.error(e));

            /* 1st Option - End */

            return;

        });             
  }

  // Fallback to the SDP munging with local renegotiation way of limiting
  // the bandwidth.
  function onSetSessionDescriptionError(error) {
      console.log('Failed to set session description: ' + error.toString());
    }
};

function updateBandwidthRestriction(sdp, bandwidth) {
  let modifier = 'AS';
  if (adapter.browserDetails.browser === 'firefox') {
    bandwidth = (bandwidth >>> 0) * 1000;
    modifier = 'TIAS';
  }
  if (sdp.indexOf('b=' + modifier + ':') === -1) {
    // insert b= after c= line.
    sdp = sdp.replace(/c=IN (.*)\r\n/, 'c=IN $1\r\nb=' + modifier + ':' + bandwidth + '\r\n');
  } else {
    sdp = sdp.replace(new RegExp('b=' + modifier + ':.*\r\n'), 'b=' + modifier + ':' + bandwidth + '\r\n');
  }
  return sdp;
}

function removeBandwidthRestriction(sdp) {
  return sdp.replace(/b=AS:.*\r\n/, '').replace(/b=TIAS:.*\r\n/, '');
}

2018 年 14 月 12 日更新:第二个选项 createOffer

问题:无法设置会话描述:InvalidStateError:无法在“RTCPeerConnection”上执行“setRemoteDescription”:无法设置远程应答 sdp:在错误状态下调用:kStable

const bandwidthSelector = document.querySelector('select#bandwidth');

bandwidthSelector.disabled = false;

// renegotiate bandwidth on the fly.
bandwidthSelector.onchange = () => {
  bandwidthSelector.disabled = true;
  const bandwidth = bandwidthSelector.options[bandwidthSelector.selectedIndex].value;

  // In Chrome, use RTCRtpSender.setParameters to change bandwidth without
  // (local) renegotiation. Note that this will be within the envelope of
  // the initial maximum bandwidth negotiated via SDP.
  if ((adapter.browserDetails.browser === 'chrome' ||
       (adapter.browserDetails.browser === 'firefox' &&
        adapter.browserDetails.version >= 64)) &&
      'RTCRtpSender' in window &&
      'setParameters' in window.RTCRtpSender.prototype) {

        $.each(peers, function( index, value ) {
            const sender = value.getSenders()[0];
            const parameters = sender.getParameters();
            if (!parameters.encodings) {
              parameters.encodings = [{}];
            }
            if (bandwidth === 'unlimited') {
              delete parameters.encodings[0].maxBitrate;
            } else {
              parameters.encodings[0].maxBitrate = bandwidth * 1000;
            }
            sender.setParameters(parameters)
            .then(() => {
              bandwidthSelector.disabled = false;
            })
            .catch(e => console.error(e));

            /* 2nd option - Start */
            value.createOffer(
                    function (local_description) {
                        console.log("Local offer description is: ", local_description);
                        value.setLocalDescription(local_description,
                            function () {
                                signaling_socket.emit('relaySessionDescription', {
                                    'peer_id': index,
                                    'session_description': local_description
                                });
                                console.log("Offer setLocalDescription succeeded");
                            },
                            function () {
                                Alert("Offer setLocalDescription failed!");
                            }
                        );
                    },
                    function (error) {
                        console.log("Error sending offer: ", error);
                    }).then(() => {
                  const desc = {
                    type: value.remoteDescription.type,
                    sdp: bandwidth === 'unlimited'
                      ? removeBandwidthRestriction(value.remoteDescription.sdp)
                      : updateBandwidthRestriction(value.remoteDescription.sdp, bandwidth)
                  };
                  console.log('Applying bandwidth restriction to setRemoteDescription:\n' +
                    desc.sdp);
                  return value.setRemoteDescription(desc);
                })
                .then(() => {
                  bandwidthSelector.disabled = false;
                })
                .catch(onSetSessionDescriptionError);

            /* 2nd option - End */

            return;

        });             
  }

  // Fallback to the SDP munging with local renegotiation way of limiting
  // the bandwidth.
  function onSetSessionDescriptionError(error) {
      console.log('Failed to set session description: ' + error.toString());
    }
};

function updateBandwidthRestriction(sdp, bandwidth) {
  let modifier = 'AS';
  if (adapter.browserDetails.browser === 'firefox') {
    bandwidth = (bandwidth >>> 0) * 1000;
    modifier = 'TIAS';
  }
  if (sdp.indexOf('b=' + modifier + ':') === -1) {
    // insert b= after c= line.
    sdp = sdp.replace(/c=IN (.*)\r\n/, 'c=IN $1\r\nb=' + modifier + ':' + bandwidth + '\r\n');
  } else {
    sdp = sdp.replace(new RegExp('b=' + modifier + ':.*\r\n'), 'b=' + modifier + ':' + bandwidth + '\r\n');
  }
  return sdp;
}

function removeBandwidthRestriction(sdp) {
  return sdp.replace(/b=AS:.*\r\n/, '').replace(/b=TIAS:.*\r\n/, '');
}

【问题讨论】:

    标签: javascript html webrtc p2p


    【解决方案1】:

    RTCRtpSender 只控制发送带宽。如果要限制接收带宽,需要使用 b=AS / b=TIAS 方式或者让接收方使用 setParameters。

    【讨论】:

    • 嗨@Philipp,我尝试了两个选项,但是,我不熟悉WebRTC,两个选项都返回错误,我可以知道哪个选项适合以及如何使其工作吗?我已经用问题一起更新了上面的代码。谢谢
    • 啊...“receiver”是指接听电话的一方,而不是 RTCRtpReceiver。术语很棘手。 “在错误状态下调用”错误可能是由于使用了 onnegotiationeeded。关于这个,stackoverflow 上有几个问题。
    • 嗨@Philipp,我终于通过向接收器发送请求以更改带宽来解决这个问题。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-02
    • 1970-01-01
    • 1970-01-01
    • 2021-10-06
    • 1970-01-01
    相关资源
    最近更新 更多