Article MSTP + MSTG video main-thread
by jib1
HTML
<script src="https://jan-ivar.github.io/polyfills/mediastreamtrackprocessor.js"></script>
<script src="https://jan-ivar.github.io/polyfills/mediastreamtrackgenerator.js"></script>
<button id="start">Start</button> polyfilled to work in all browsers!<br><br>
<video id="video1" width="240" height="180" autoplay muted></video>
<video id="video2" width="240" height="180" autoplay muted></video>
JavaScript
start.onclick = async () => {
video1.srcObject = await navigator.mediaDevices.getUserMedia({video: true});
const mstp = new MediaStreamTrackProcessor({track: video1.srcObject.getVideoTracks()[0]});
const mstg = new MediaStreamTrackGenerator({kind: "video"});
video2.srcObject = new MediaStream([mstg]);
await mstp.readable.pipeThrough(new TransformStream({transform})).pipeTo(mstg.writable);
};
const canvas = new OffscreenCanvas(640, 480);
const ctx = canvas.getContext('2d', {desynchronized: true});
ctx.translate(canvas.width, 0);
ctx.scale(-1, 1);
function transform(frame, controller) {
ctx.drawImage(frame, 0, 0);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const {data} = imageData;
for (let i = 0; i < data.length; i += 4) {
const r = data[i], g = data[i + 1], b = data[i + 2];
data[i] = 0.393 * r + 0.769 * g + 0.189 * b;
data[i + 1] = 0.349 * r + 0.686 * g + 0.168 * b;
data[i + 2] = 0.272 * r + 0.534 * g + 0.131 * b;
}
ctx.putImageData(imageData, 0, 0);
controller.enqueue(new VideoFrame(canvas, {timestamp: frame.timestamp}));
frame.close();
}