Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save djkskqyr3/5355f8c8902517f39140e367d2ae72ed to your computer and use it in GitHub Desktop.
Save djkskqyr3/5355f8c8902517f39140e367d2ae72ed 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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment