Article WebRTC swap tracks
by jib1
HTML
<video id="videoA" width="320" height="240" autoplay muted></video>
<video id="videoB" width="320" height="240" autoplay></video>
<button onclick="camStream.getTracks().forEach(t => t.stop())">Stop Example</button><br>
<div id="div"></div>
<script src="https://jan-ivar.github.io/blacksilence/blacksilence.js"></script>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
JavaScript
let pc1 = new RTCPeerConnection(), pc2 = new RTCPeerConnection(), camStream;
let swapTracks = (s1, s2) => Promise.all([s1.replaceTrack(s2.track), s2.replaceTrack(s1.track)]);
(async () => {
try {
camStream = await navigator.mediaDevices.getUserMedia({video: true});
let blankStream = new MediaStream([black()]);
let videos = {[camStream.id]: videoA, [blankStream.id]: videoB};
let senderA = pc1.addTrack(camStream.getVideoTracks()[0], camStream);
let senderB = pc1.addTrack(blankStream.getVideoTracks()[0], blankStream);
pc2.ontrack = ({streams: [stream]}) => {
let video = videos[stream.id];
if (!video.srcObject) video.srcObject = stream;
}
await new Promise(resolve => pc1.oniceconnectionstatechange =
() => pc1.iceConnectionState == "connected" && resolve());
await wait(3000);
await swapTracks(senderA, senderB);
} catch (e) {
console.log(e)
}
})();
var wait = ms => new Promise(resolve => setTimeout(resolve, ms));
pc1.onicecandidate = e => pc2.addIceCandidate(e.candidate);
pc2.onicecandidate = e => pc1.addIceCandidate(e.candidate);
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);
};