首页 > Web开发 > 详细

webrtc限制发送速率

时间:2020-01-15 18:02:59      阅读:135      评论:0      收藏:0      [点我收藏+]

webrtc官方的代码示例:

/*
 *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree.
 */
/* global TimelineDataSeries, TimelineGraphView */

use strict;

const remoteVideo = document.querySelector(video#remoteVideo);
const localVideo = document.querySelector(video#localVideo);
const callButton = document.querySelector(button#callButton);
const hangupButton = document.querySelector(button#hangupButton);
const bandwidthSelector = document.querySelector(select#bandwidth);
hangupButton.disabled = true;
callButton.onclick = call;
hangupButton.onclick = hangup;

let pc1;
let pc2;
let localStream;

// Can be set in the console before making a call to test this keeps
// within the envelope set by the SDP. In kbps.
const maxBandwidth = 0;

let bitrateGraph;
let bitrateSeries;

let packetGraph;
let packetSeries;

let lastResult;

const offerOptions = {
  offerToReceiveAudio: 0,
  offerToReceiveVideo: 1
};

function gotStream(stream) {
  hangupButton.disabled = false;
  console.log(Received local stream);
  localStream = stream;
  localVideo.srcObject = stream;
  localStream.getTracks().forEach(track => pc1.addTrack(track, localStream));
  console.log(Adding Local Stream to peer connection);

  pc1.createOffer(
      offerOptions
  ).then(
      gotDescription1,
      onCreateSessionDescriptionError
  );

  bitrateSeries = new TimelineDataSeries();
  bitrateGraph = new TimelineGraphView(bitrateGraph, bitrateCanvas);
  bitrateGraph.updateEndDate();

  packetSeries = new TimelineDataSeries();
  packetGraph = new TimelineGraphView(packetGraph, packetCanvas);
  packetGraph.updateEndDate();
}

function onCreateSessionDescriptionError(error) {
  console.log(Failed to create session description:  + error.toString());
}

function call() {
  callButton.disabled = true;
  bandwidthSelector.disabled = false;
  console.log(Starting call);
  const servers = null;
  pc1 = new RTCPeerConnection(servers);
  console.log(Created local peer connection object pc1);
  pc1.onicecandidate = onIceCandidate.bind(pc1);

  pc2 = new RTCPeerConnection(servers);
  console.log(Created remote peer connection object pc2);
  pc2.onicecandidate = onIceCandidate.bind(pc2);
  pc2.ontrack = gotRemoteStream;

  console.log(Requesting local stream);
  navigator.mediaDevices.getUserMedia({video: true})
      .then(gotStream)
      .catch(e => alert(getUserMedia() error:  + e.name));
}

function gotDescription1(desc) {
  console.log(Offer from pc1 \n + desc.sdp);
  pc1.setLocalDescription(desc).then(
      () => {
        pc2.setRemoteDescription(desc)
            .then(() => pc2.createAnswer().then(gotDescription2, onCreateSessionDescriptionError),
                onSetSessionDescriptionError);
      }, onSetSessionDescriptionError
  );
}

function gotDescription2(desc) {
  pc2.setLocalDescription(desc).then(
      () => {
        console.log(Answer from pc2 \n + desc.sdp);
        let p;
        if (maxBandwidth) {
          p = pc1.setRemoteDescription({
            type: desc.type,
            sdp: updateBandwidthRestriction(desc.sdp, maxBandwidth)
          });
        } else {
          p = pc1.setRemoteDescription(desc);
        }
        p.then(() => {}, onSetSessionDescriptionError);
      },
      onSetSessionDescriptionError
  );
}

function hangup() {
  console.log(Ending call);
  localStream.getTracks().forEach(track => track.stop());
  pc1.close();
  pc2.close();
  pc1 = null;
  pc2 = null;
  hangupButton.disabled = true;
  callButton.disabled = false;
  bandwidthSelector.disabled = true;
}

function gotRemoteStream(e) {
  if (remoteVideo.srcObject !== e.streams[0]) {
    remoteVideo.srcObject = e.streams[0];
    console.log(Received remote stream);
  }
}

function getOtherPc(pc) {
  return pc === pc1 ? pc2 : pc1;
}

function getName(pc) {
  return pc === pc1 ? pc1 : pc2;
}

function onIceCandidate(event) {
  getOtherPc(this)
      .addIceCandidate(event.candidate)
      .then(onAddIceCandidateSuccess)
      .catch(onAddIceCandidateError);

  console.log(`${getName(this)} ICE candidate:\n${event.candidate ? event.candidate.candidate : (null)}`);
}

function onAddIceCandidateSuccess() {
  console.log(AddIceCandidate success.);
}

function onAddIceCandidateError(error) {
  console.log(Failed to add ICE Candidate:  + error.toString());
}

function onSetSessionDescriptionError(error) {
  console.log(Failed to set session description:  + error.toString());
}

// 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.
  //在chrome中,使用RTCRtpSender.setParameters方法来改变带宽而不使用(本地)重新协商,
  //注意,这个带宽大小只能在最初的媒体协商的最大带宽之内。
  if ((adapter.browserDetails.browser === chrome ||
       (adapter.browserDetails.browser === firefox &&
        adapter.browserDetails.version >= 64)) &&
      RTCRtpSender in window &&
      setParameters in window.RTCRtpSender.prototype) {
    const sender = pc1.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));
    return;
  }
  // Fallback to the SDP munging with local renegotiation way of limiting the bandwidth.
  //回退到SDP,用本地重新协商的方式限制带宽。
  console.log("Fallback to the SDP munging with local renegotiation way of limiting");
  pc1.createOffer()
      .then(offer => pc1.setLocalDescription(offer))
      .then(() => {
        const desc = {
          type: pc1.remoteDescription.type,
          sdp: bandwidth === unlimited ?
          removeBandwidthRestriction(pc1.remoteDescription.sdp) :
          updateBandwidthRestriction(pc1.remoteDescription.sdp, bandwidth)
        };
        console.log(Applying bandwidth restriction to setRemoteDescription:\n +
        desc.sdp);
        return pc1.setRemoteDescription(desc);
      })
      .then(() => {
        bandwidthSelector.disabled = false;
      })
      .catch(onSetSessionDescriptionError);
};

function updateBandwidthRestriction(sdp, bandwidth) {
  let modifier = AS;
  if (adapter.browserDetails.browser === firefox) {
      //>>>无符号右移,大于0的数值位运算后结果不变,任何非数值变量做此运算都会变为0
    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/, ‘‘);
}

// query getStats every second
//每秒获取Senders状态
window.setInterval(() => {
  if (!pc1) {
    return;
  }
  const sender = pc1.getSenders()[0];
  if (!sender) {
    return;
  }
  sender.getStats().then(res => {
    res.forEach(report => {
      let bytes;
      let packets;
      if (report.type === outbound-rtp) {
        if (report.isRemote) {
          return;
        }
        const now = report.timestamp;
        bytes = report.bytesSent;
        packets = report.packetsSent;
        if (lastResult && lastResult.has(report.id)) {
          // calculate bitrate
          const bitrate = 8 * (bytes - lastResult.get(report.id).bytesSent) /
            (now - lastResult.get(report.id).timestamp);

          // append to chart
          bitrateSeries.addPoint(now, bitrate);
          bitrateGraph.setDataSeries([bitrateSeries]);
          bitrateGraph.updateEndDate();

          // calculate number of packets and append to chart
          packetSeries.addPoint(now, packets -
            lastResult.get(report.id).packetsSent);
          packetGraph.setDataSeries([packetSeries]);
          packetGraph.updateEndDate();
        }
      }
    });
    lastResult = res;
  });
}, 1000);

webrtc限制发送速率

原文:https://www.cnblogs.com/dch0/p/12197866.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!