PeerConnection 2 gUMs

by Alex Chronopoulos

HTML

<video id="remote" controls></video>
<div id="div"><br></div>

JavaScript

var log = msg => div.innerHTML += msg + "<br>";

let stream;
let pc1;
let pc2;
async function sendTracks() {
  // Start the 1st gUM
  stream = await navigator.mediaDevices.getUserMedia({audio: true, video: true});
  const videoTrack = stream.getVideoTracks()[0];
  const audioTrack = stream.getAudioTracks()[0];
  
  // Set up the PCs
  pc1 = new RTCPeerConnection();
  pc2 = new RTCPeerConnection();
  
  pc1.addEventListener('icecandidate', async e => await pc2.addIceCandidate(e.candidate));
  pc1.addTrack(videoTrack, stream);
  pc1.addTrack(audioTrack, stream);
  const offer = await pc1.createOffer({
    offerToReceiveAudio: 1
  });
  await pc1.setLocalDescription(offer);

  pc2.addEventListener('icecandidate', async e => await pc1.addIceCandidate(e.candidate));
  pc2.addEventListener('track', e => {
    remote.srcObject = e.streams[0];
    remote.play();
  });
  await pc2.setRemoteDescription(offer);
  const answer = await pc2.createAnswer();
  
  await pc2.setLocalDescription(answer);
  await pc1.setRemoteDescription(answer);
  
  // Wait a little before starting the 2nd gUM
  await new Promise(r => setTimeout(r, 5000));

  // First stop the existing tracks
  stream.getTracks().forEach(track => track.stop());
  
  // 2nd gUM
  const newStream = await navigator.mediaDevices.getUserMedia({audio: true, video: true});
  stream.removeTrack(videoTrack);
  stream.removeTrack(audioTrack);
  stream.addTrack(newStream.getVideoTracks()[0]);
  stream.addTrack(newStream.getAudioTracks()[0]);
  
  // Replace tracks in PC
  let sender1 = pc1.getSenders()[0];
  let sender2 = pc1.getSenders()[1];
  await sender1.replaceTrack(stream.getVideoTracks()[0]);
  await sender2.replaceTrack(stream.getAudioTracks()[0]);
}

sendTracks();