我试图通过将此示例与我现有的多参与者视频通话代码结合使用,来更改WebRTC P2P视频通话的实时带宽:

样本:https://webrtc.github.io/samples/src/content/peerconnection/bandwidth/

当我通过Chrome浏览WebRTC内部时,

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

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

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

问题:未被捕获的TypeError:receive.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/, '');
}


更新14/12/2018:第二个选项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/, '');
}

最佳答案

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

09-16 19:34