Невозможно ограничить пропускную способность приема для нескольких участников WebRTC P2P - PullRequest
0 голосов
/ 13 декабря 2018

Я пытаюсь изменить пропускную способность на лету для видеовызова WebRTC P2P, используя этот пример, объединяющийся с моим существующим кодом, который является видеовызовом для нескольких участников:

Пример :https://webrtc.github.io/samples/src/content/peerconnection/bandwidth/

Когда я заглядываю в WebRTC Internals через Chrome,

bitsReceivedPerSecond для send (ssrc) (видео) сбрасывается навыбранная пропускная способность.Однако bitsReceivedPerSecond для recv (ssrc) (видео) по-прежнему остаются без изменений.Могу ли я узнать, как применять изменения пропускной способности при отправке и получении?

Ниже приведены мои коды, было бы здорово, если бы вы могли помочь указать на мои ошибки, заранее спасибо.

Обновление 14/12/2018: Добавлена ​​1-я опция для получателя для кодов

Проблема: Uncaught 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: 2-й вариант createOffer

Проблема: Не удалось установить описание сеанса: InvalidStateError: Не удалось выполнить setRemoteDescription в«RTCPeerConnection»: не удалось установить удаленный ответ. 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/, '');
}

1 Ответ

0 голосов
/ 14 декабря 2018

RTCRtpSender контролирует только полосу отправки.Если вы хотите ограничить полосу пропускания приема, вам нужно использовать способ b = AS / b = TIAS или заставить получателя использовать setParameters.

...