Article WebRTC two-way transceiver replaceTrack

by jib1

HTML

One side:<br>
<video id="videoA" width="320" height="240" autoplay controls></video>
<video id="videoB" width="320" height="240" autoplay></video><br>
Other side:<br>
<video id="videoC" width="320" height="240" autoplay controls></video>
<video id="videoD" width="320" height="240" autoplay></video><br>
<div id="div"></div>
<button onclick="camStream.getTracks().forEach(t => t.stop())">Stop Example</button><br>
<script src="https://jan-ivar.github.io/localloop/localloop.js"></script>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>

JavaScript

let camStream;

(async () => {
  try {
    const [pc1, pc2] = localPeerConnectionLoop(), noise = whiteNoise();
    camStream = await navigator.mediaDevices.getUserMedia({video: true, audio: true});

    let transceivers = [
      pc1.addTransceiver(camStream.getVideoTracks()[0]),
      pc1.addTransceiver(camStream.getAudioTracks()[0]),
      pc1.addTransceiver(noise)
    ];
    for (let [pc, videoL, videoR] of [[pc1, videoA, videoB], [pc2, videoC, videoD]]) {
      pc.ontrack = ({transceiver}) => {
        if (transceiver.mid == transceivers[2].mid) {
          videoR.srcObject = new MediaStream([transceiver.receiver.track]);
        } else {
          if (!videoL.srcObject || videoL.srcObject.getTracks().length == 2) {
            videoL.srcObject = new MediaStream([transceiver.receiver.track]);
          } else {
            videoL.srcObject.addTrack(transceiver.receiver.track);
          }
        }
      }
    }
    await new Promise(r => pc2.onsignalingstatechange = () => pc2.signalingState == "have-remote-offer" && r());

    let [tc1, tc2, tc3] = transceivers.map(othertc => pc2.getTransceivers().find(tc => tc.mid == othertc.mid));
    tc1.direction = tc2.direction = tc3.direction = "sendrecv";
    await Promise.all([
      tc1.sender.replaceTrack(camStream.getVideoTracks()[0]),
      tc2.sender.replaceTrack(camStream.getAudioTracks()[0]),
      tc3.sender.replaceTrack(noise)
    ]);
    div.innerHTML = `${pc2.getTransceivers().length} transceivers total`;
  } catch (e) {
    console.log(e)
  }
})();