Article async WebRTC stats demo

by jib1

HTML

<video id="video1" width="160" height="120" autoplay muted></video>
<video id="video2" width="160" height="120" autoplay></video><br>
<label><input type="checkbox" onclick="mute()">mute</label>
<div id="div"></div><br><div id="statsdiv"></div>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>

JavaScript

const pc1 = new RTCPeerConnection(), pc2 = new RTCPeerConnection();

(async () => {
  try {
    const stream = await navigator.mediaDevices.getUserMedia({video: true, audio: true});
    stream.getTracks().forEach(track => pc1.addTrack(track, stream));
    video1.srcObject = stream;

    await new Promise(resolve => pc1.oniceconnectionstatechange =
        () => pc1.iceConnectionState == "connected" && resolve());

    while (true) {
      let html = "", stats = await pc1.getStats();
      for (const stat of stats.values()) {
        if (stat.isRemote) continue; // <-- can go away eventually, but not yet.
        switch (stat.type) {
          case "outbound-rtp": {
            html += dumpOutbound(stat) + "<br>";
            let remote = stats.get(stat.remoteId); // <-- Like this!
            if (remote) html += "Remote " + dumpInbound(remote) + "<br>";
            break;
          }
          case "inbound-rtp": {
            html += dumpInbound(stat) + "<br>";
            let remote = stats.get(stat.remoteId); // <-- Like this!
            if (remote) html += "Remote " + dumpOutbound(remote) + "<br>";
            break;
          }
        }
      }
      update(statsdiv, `<small>${html}</small>`);
      await wait(100);
    }
  } catch(e) {
    log(e);
  }
})();

pc1.onicecandidate = e => pc2.addIceCandidate(e.candidate);
pc2.onicecandidate = e => pc1.addIceCandidate(e.candidate);
pc1.oniceconnectionstatechange = e => log(pc1.iceConnectionState);

pc1.onnegotiationneeded = async e => {
  await pc1.setLocalDescription(await pc1.createOffer());
  await pc2.setRemoteDescription(pc1.localDescription);
  await pc2.setLocalDescription(await pc2.createAnswer());
  await pc1.setRemoteDescription(pc2.localDescription);
}
pc2.ontrack = e => video2.srcObject = e.streams[0];

var mute = () => video1.srcObject.getTracks().forEach(t => t.enabled = !t.enabled);
var log = msg => div.innerHTML += msg + "<br>";
var update = (div, msg) => div.innerHTML = msg;
var wait = ms =>...