100% on-device
Compress an MP4 in your browser
Shrink a clip to fit under a size limit — email, Discord, WhatsApp — or set your own quality. No upload, no sign-up; your video never leaves this tab.
How it works
- Drop your MP4. It is read straight into this tab. Nothing is sent to a server.
- Name a size, not a bitrate. Type a limit (or tap Email 25 MB · WhatsApp 16 MB · Discord 10 MB) and the tool works backwards from your budget and the clip's duration to the bitrate that lands under it — and shows you the estimate before you commit. Prefer to steer by feel? Switch to quality mode.
- Download. The video is re-encoded on your device by FFmpeg compiled to WebAssembly, then saved locally.
In our own test, a 1.9 MB 720p clip capped at 1 MB came out at 814 KB — 58% smaller.
Re-encoding an MP4 starts from what the first encoder already discarded
An MP4 is a container; its size is set by the H.264 inside it. H.264 is lossy - the first encode quantised away high-frequency detail and rebuilt most frames as predictions of their neighbours. Compressing again decodes that approximation back to pixels and quantises it a second time, so the previous pass’s artefacts become signal the new pass must faithfully preserve. That is generation loss.
It is also why a clip forwarded through two chat apps will not sharpen up, whatever bitrate you give it - each hop encoded the previous hop’s output. If the camera original or the editor export is still on the drive, compress that instead. A first-generation encode from the source is a different file from a third-generation one at the same size.
CRF asks for a quality; a bitrate asks for a size
H.264 encoders offer two rate-control modes. Constant rate factor holds a perceptual quality and lets the size fall where it falls, so the result is unknowable until it finishes. Target bitrate fixes bits per second and lets quality float, and it is the only mode that can honour a hard cap: the encoder is handed your byte budget times eight, divided by the duration, less whatever the audio track costs.
The cost is that a fixed bitrate treats every second alike. A static talking head has bits to spare; handheld footage, rain, confetti or grass will smear at the same number, because complexity varies and the budget does not. Naming a slightly larger cap, or letting the resolution drop, buys back more than any encoder setting will.
Questions
Is my video really not uploaded?
Yes — and not as a policy, as a fact of how it is built. There is no upload endpoint: the file is read straight into this browser tab and compressed by code running on your own machine. You can watch the Network tab while it works, or pull your Wi-Fi out mid-compression and it will still finish. Nothing is stored, nothing is queued, and there is no account.
Why is the first compression slow to start?
The video engine (FFmpeg, ~30 MB of WebAssembly) downloads once, the first time you compress something. After that the browser caches it, and it is shared with the GIF and audio tabs — so the second run, and every run after it, starts immediately.
Will it fit exactly under my limit?
That is the whole design. The size you type is a hard ceiling: the bitrate is solved from your byte budget, and if the encoder overshoots anyway the tool rescales and re-encodes rather than handing you a file that misses the cap. If a limit is too tight to be watchable it tells you up front instead of quietly producing a smear.
What about MOV, MKV, AVI or WebM?
All of them work — drop them on the same tab. FFmpeg identifies a video by reading its bytes, not its file name, so the container makes no difference to it. Whatever goes in, an MP4 (H.264/AAC) comes out, because that is the one format email, Discord, WhatsApp and every phone actually play.
Other formats
The same workbench handles all of them — pick a tab above, or start from its own page: