Article Sender transform vp8
by jib1
HTML
<script src="https://jan-ivar.github.io/samples/src/content/insertable-streams/video-analyzer/js/adapter-shim.js"></script>
<button id="start">Start!</button>
<label><input type="checkbox" id="descramble" checked>descramble</label>
<button id="halt">Stop!</button><br>
<video id="video1" width="360" height="270" autoplay muted></video>
<video id="video2" width="360" height="270" autoplay></video><br>
<div id="div"></div>
JavaScript
const chromeCfg = {encodedInsertableStreams: true}; // needed by chrome shim
let pc1 = new RTCPeerConnection(chromeCfg), pc2 = new RTCPeerConnection(chromeCfg);
start.onclick = async () => {
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 pc2.setLocalDescription(); await pc1.setRemoteDescription(pc2.localDescription);
}
video1.srcObject = await navigator.mediaDevices.getUserMedia({video: true});
const sender = pc1.addTrack(video1.srcObject.getTracks()[0], video1.srcObject);
sender.transform = new RTCRtpScriptTransform(worker, {side: "send"});
video2.srcObject = (await new Promise(r => pc2.ontrack = r)).streams[0];
const [receiver] = pc2.getReceivers();
receiver.transform = new RTCRtpScriptTransform(worker, {side: "receive"});
};
descramble.onclick = () => { worker.postMessage({descramble: descramble.checked}); }
halt.onclick = () => {
video1.srcObject.getTracks().forEach(track => track.stop());
video2.srcObject.getTracks().forEach(track => track.stop());
pc1.close();
pc2.close();
pc1 = new RTCPeerConnection(chromeCfg);
pc2 = new RTCPeerConnection(chromeCfg);
}
// The rest is in a worker:
const worker = new Worker(`data:text/javascript,(${work.toString()})()`);
function work() {
let descramble = true;
onmessage = ({data}) => {
if ("descramble" in data) descramble = data.descramble;
if ("rtctransform" in data) onrtctransform({transformer: data.rtctransform}); /* needed by chrome shim: */
};
onrtctransform = async ({transformer: {readable, writable, options}}) => {
await readable.pipeThrough(new TransformStream({transform})).pipeTo(writable);
function transform(chunk, controller) {
const bytes = new...