WebCodecs exposes the browser's own, often hardware, codecs frame by frame: VideoEncoder, VideoDecoder, AudioEncoder, AudioDecoder and ImageDecoder, working on VideoFrame, AudioData and EncodedVideoChunk objects. Video editors, cloud gaming and low-latency streaming over WebTransport (WebTransport) use it where MediaRecorder and MSE hide too much.
const chunks = [];
const encoder = new VideoEncoder({ output: (chunk) => chunks.push(chunk), error: console.error });
encoder.configure({ codec: 'vp09.00.10.08', width: 640, height: 360, bitrate: 1e6, framerate: 30 });
const g = new OffscreenCanvas(640, 360).getContext('2d');
for (let i = 0; i < 60; i++) {
g.fillStyle = `hsl(${i * 6} 80% 50%)`;
g.fillRect(0, 0, 640, 360);
const frame = new VideoFrame(g.canvas, { timestamp: (i * 1e6) / 30 }); // microseconds
encoder.encode(frame, { keyFrame: i % 30 === 0 });
frame.close(); // release memory immediately
}
await encoder.flush(); // Chrome 152: 60 chunks, 121,210 bytesCheck VideoEncoder.isConfigSupported(config) first and run heavy jobs in a worker. Chunks are raw codec data: wrap them in MP4 or WebM with Mediabunny 7,203 (https://github.com/Vanilagy/mediabunny 7,203 ) (npm 2,036 i mediabunny, MPL-2.0).