How it works

Video is encoded by a WebAssembly build of FFmpeg running in your browser. Images are decoded by a WebAssembly build of libheif and re-encoded through a canvas. Both engines are downloaded once and cached; your files are never part of any request.

What crosses the network

Every network request this site makes.
WhatWhenDirection
HTML, CSS, JavaScriptFirst visit, then from cacheDownload
FFmpeg core (.wasm)First video compression onlyDownload
libheif decoderFirst HEIC conversion onlyDownload
Your filesNever
Analytics, trackers, fontsNever — there are none

You do not have to take that table on faith: how to confirm it in DevTools →

Turning a target size into a bitrate

File size is bitrate multiplied by duration. Both of the other two are known — you choose the size, and the browser reads the duration out of the video's metadata — so the bitrate falls out of the arithmetic:

video kbps = (target bytes × 8 ÷ 1000 ÷ duration) − audio kbps

Audio is held at 96 kbps, and the resulting video bitrate is trimmed by a few percent before encoding. That margin covers container overhead and keyframe placement, which move the final size slightly in ways the formula cannot predict. Aiming exactly at the limit would mean landing over it some of the time, and a file one byte over the cap is a failed upload, not a slightly worse one.

Output is H.264 video and AAC audio in an MP4 with faststart, which puts the index at the front of the file so it can play before it has finished downloading.

Why metadata removal is a re-encode

Converting an image here decodes it to pixels and encodes a fresh JPG. A canvas holds pixels and nothing else, so the output has no EXIF block to begin with — removal is not an extra step, it is what happens by default.

That is also why keeping metadata takes work: when you turn removal off, the EXIF segment is lifted from the source file and spliced back into the output. For HEIC sources it often cannot be, because the metadata lives in the HEIF container rather than in the image stream the decoder returns. The interface reports which happened instead of assuming.

Working offline

A service worker caches the page and both engines. Once you have compressed something the tool keeps working with the network off — which is the strongest available evidence that nothing is being uploaded, since a round trip to a server you cannot reach is not something caching can fake.

Limitations worth knowing

  • Encoding in WebAssembly is slower than a native FFmpeg build. Long clips are noticeably faster on a laptop than on a phone.
  • The first compression of a session waits for the encoder to download. After that it is cached.
  • Very low bitrates produce visibly poor results. If a clip is long, trimming it costs far less quality than compressing it harder.
  • Everything happens in a browser tab, so memory limits apply. Very large source files can fail on low-memory devices.