Project 34, Media and real-time
Browser Video Editor
Load a clip, drag the handles to trim it, pick a filter and a title, and export an MP4. Every frame is encoded in your browser with WebCodecs.
- Main API
- WebCodecs VideoEncoder
- Container
- mp4-muxer
- Fallback
- MediaRecorder
- Your browser
- Checking
Edit a clip
0.0 s0.0 s
Load a video to start
How it works
- Pick framesThe video plays from the in point to the out point. requestVideoFrameCallback hands over each frame as it is shown.
- Edit the frameEach frame is drawn on a canvas with the filter and title, then wrapped in a VideoFrame with its timestamp.
- Encode and packVideoEncoder compresses the frames. mp4-muxer puts the chunks into an MP4 file you can download.
import { Muxer, ArrayBufferTarget } from "https://cdn.jsdelivr.net/npm/mp4-muxer@5.2.2/+esm";
const muxer = new Muxer({ target: new ArrayBufferTarget(), video: { codec: "avc", width, height }, fastStart: "in-memory" });
const encoder = new VideoEncoder({ output: (chunk, meta) => muxer.addVideoChunk(chunk, meta), error: console.error });
encoder.configure({ codec: "avc1.42001f", width, height, bitrate: 4e6, framerate: 30 });
video.requestVideoFrameCallback(function onFrame(now, info) {
ctx.drawImage(video, 0, 0); // plus filter and title
const frame = new VideoFrame(canvas, { timestamp: (info.mediaTime - start) * 1e6 });
encoder.encode(frame, { keyFrame: n++ % 60 === 0 }); frame.close();
video.requestVideoFrameCallback(onFrame);
});