Skip to content

Instantly share code, notes, and snippets.

@saravanannkl
Created November 23, 2021 01:02
Show Gist options
  • Save saravanannkl/3c39f856c8c440a1f8c76bddb5ceab00 to your computer and use it in GitHub Desktop.
Save saravanannkl/3c39f856c8c440a1f8c76bddb5ceab00 to your computer and use it in GitHub Desktop.
Media stream video frame I420A to I420 converter
// Based on https://web.dev/mediastreamtrack-insertable-media-processing/
// Uses Webcodecs API, which is supported only in Chrome as of November 2021
function convertI420AFrameToI420Frame(frame) {
const { width, height } = frame.codedRect;
// Y, U, V, Alpha values are stored sequentially. Take only YUV values
const buffer = new Uint8Array(width * height * 3);
frame.copyTo(buffer, { rect: frame.codedRect });
const init = {
timestamp: 0,
codedWidth: width,
codedHeight: height,
format: "I420"
};
// eslint-disable-next-line no-undef
return new VideoFrame(buffer, init);
}
function transform(stream) {
const videoTrack = stream.getVideoTracks()[0];
const trackProcessor = new MediaStreamTrackProcessor({
track: videoTrack
});
const trackGenerator = new MediaStreamTrackGenerator({ kind: "video" });
const transformer = new TransformStream({
async transform(videoFrame, controller) {
const newFrame = convertI420AFrameToI420Frame(videoFrame);
videoFrame.close();
controller.enqueue(newFrame);
}
});
trackProcessor.readable
.pipeThrough(transformer)
.pipeTo(trackGenerator.writable);
const processedStream = new MediaStream();
processedStream.addTrack(trackGenerator);
return processedStream;
}
@saravanannkl
Copy link
Author

saravanannkl commented Nov 23, 2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment