article setCodecPreferences single-preference example

My starting point.

by jib1

HTML

<video id="video1" width="160" height="120" autoplay muted></video>
<video id="video2" width="160" height="120" autoplay></video><br>
<div id="div" style="white-space: pre;"></div>

JavaScript

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

(async () => {
  try {
    const stream = await navigator.mediaDevices.getUserMedia({video: true});
    const [track] = stream.getVideoTracks();
    pc1.addTrack(track, stream); // send camera track from pc1 → pc2
    pc2.addTrack(track, stream); // send camera track from pc2 → pc1

    const [transceiver1] = pc1.getTransceivers();
    const codecs1 = RTCRtpReceiver.getCapabilities("video").codecs;
    transceiver1.setCodecPreferences(sortByMimeTypes(codecs1, ["video/H264", "video/VP8", "video/VP9"])); // <---
    console.log(`pc1 prefers ${[...new Set(codecs1.map(({mimeType}) => mimeType))]}`);
    console.log(`pc2 has no preference`);

    video2.srcObject = (await new Promise(r => pc2.ontrack = r)).streams[0];
    const unmuted2 = new Promise(r => video2.srcObject.getVideoTracks()[0].onunmute = r);

    video1.srcObject = (await new Promise(r => pc1.ontrack = r)).streams[0];
    const unmuted1 = new Promise(r => video1.srcObject.getVideoTracks()[0].onunmute = r);
    await Promise.all([unmuted1, unmuted2]);
    console.log(`pc1 is sending ${(await getOutboundCodecStat(pc1)).mimeType}`);
    console.log(`pc2 is sending ${(await getOutboundCodecStat(pc2)).mimeType}`);
  } catch (e) {
    console.log(e);
  }
})();

function sortByMimeTypes(codecs, preferredOrder) {
  return codecs.sort((a, b) => {
    const indexA = preferredOrder.indexOf(a.mimeType);
    const indexB = preferredOrder.indexOf(b.mimeType);
    const orderA = indexA >= 0 ? indexA : Number.MAX_VALUE;
    const orderB = indexB >= 0 ? indexB : Number.MAX_VALUE;
    return orderA - orderB;
  });
}

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

pc1.onnegotiationneeded = async () => {
  await pc1.setLocalDescription();
  await pc2.setRemoteDescription(pc1.localDescription);
  await...