Article WebRTC scaleResolutionDownBy

by jib1

HTML

<table><tr>
  <td><video id="video1" autoplay></video></td>
  <td><video id="video2" autoplay></video></td></tr>
  <tr><td id="info1">0x0</td><td id="info2">0x0</td></tr>
  <tr><td id="info3">0 bps</td></tr>
</table><div id="div"></div>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>

JavaScript

var pc1 = new RTCPeerConnection(), pc2 = new RTCPeerConnection();
var sendWidth = 320, maxBitrate = 60000;

navigator.mediaDevices.getUserMedia({video: true})
  .then(stream => {
    video1.srcObject = stream;
    setInterval(() => update(info1, dimensions(video1)), 1000);
    let track = stream.getVideoTracks()[0];
    let sender = pc1.addTrack(track, stream);
    let sourceWidth = track.getSettings().width;
    return sender.setParameters({encodings: [{maxBitrate, scaleResolutionDownBy: sourceWidth / sendWidth}]})
  })
  .catch(log);

pc2.ontrack = e => {
   video2.srcObject = e.streams[0];
   setInterval(() => update(info2, dimensions(video2)), 1000);
   setInterval(() => pc1.getStats()
     .then(stats => update(info3, findStat(stats, "outbound-rtp").bitrateMean.toFixed(0) + " bps"))
     .catch(log), 1000);
};

var dimensions = video => video.videoWidth +"x"+ video.videoHeight;
var findStat = (map, type) => [...map.values()].find(stat => stat.type == type && !stat.isRemote);

pc1.onicecandidate = e => pc2.addIceCandidate(e.candidate);
pc2.onicecandidate = e => pc1.addIceCandidate(e.candidate);
pc1.onnegotiationneeded = e =>
  pc1.createOffer().then(d => pc1.setLocalDescription(d))
  .then(() => pc2.setRemoteDescription(pc1.localDescription))
  .then(() => pc2.createAnswer()).then(d => pc2.setLocalDescription(d))
  .then(() => pc1.setRemoteDescription(pc2.localDescription))
  .catch(log);

var log = msg => div.innerHTML += "<br>" + msg;
var update = (div, msg) => div.innerHTML = msg;