Skip to content

Instantly share code, notes, and snippets.

@saravanannkl
Created November 23, 2021 01:02
Show Gist options
  • Select an option

  • Save saravanannkl/3c39f856c8c440a1f8c76bddb5ceab00 to your computer and use it in GitHub Desktop.

Select an option

Save saravanannkl/3c39f856c8c440a1f8c76bddb5ceab00 to your computer and use it in GitHub Desktop.

Revisions

  1. saravanannkl created this gist Nov 23, 2021.
    42 changes: 42 additions & 0 deletions mediastream-I420A-to-I420-converter.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,42 @@
    // 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;
    }