Most "compress a video" problems are really one of two problems: a file that will not fit through email, or a file that takes too long to upload. Both are solved by the same two settings, and it helps to know which one to reach for first.
One line, and it is the same line professionals use:
ffmpeg -i input.mp4 -c:v libx264 -crf 28 -preset slow -c:a aac -b:a 128k output.mp4
-crf 28 is the quality dial, -preset slow tells the encoder to spend more
time finding savings, and the audio is re-encoded to a sane 128 kbps. Nothing
else is needed for the common case.
The two knobs that matter
CRF: how much detail to keep
CRF — Constant Rate Factor — is a quality target, not a size target. Lower means better and bigger. The scale runs 0–51 and the useful part is narrow:
| CRF | What it is for |
|---|---|
| 18 | Near-transparent. Archival, or footage you will edit again |
| 23 | The default. Good for almost everything |
| 28 | Visibly compressed on detailed motion, still fine for talking heads |
| 32+ | Getting it under a hard limit, and it shows |
The encoder then spends whatever bitrate it needs to hit that quality, which is why CRF gives you a consistent-looking result across clips and a fixed bitrate does not.
Resolution: how many pixels to keep at all
This is the knob people forget, and it is usually the bigger win. Going from 1080p to 480p throws away about three quarters of the pixels before the quality setting applies:
ffmpeg -i input.mp4 -vf "scale=-2:480" -c:v libx264 -crf 28 -c:a copy output.mp4
-2 on the width means "work it out from the height, and keep it an even
number" — H.264 requires even dimensions, and -2 is how you avoid doing that
arithmetic yourself.
If the video will be watched in a chat window or an email client, 480p is generous. Compressing 1080p to fit a limit, when nobody will view it larger than a postcard, is throwing away quality to preserve pixels that never get shown.
Getting under a hard limit
Email attachment limits are the usual reason anyone is here. The approach that works:
- Drop the resolution first. 1080p → 720p, or → 480p if it is going to be watched small. This is free quality compared to what CRF costs you.
- Then raise CRF in steps of 2 from 23 until the file fits.
- Check the audio. For speech,
-b:a 96kis transparent and saves real space on a long recording. For music, leave it at 128k or above. - Watch fifteen seconds of the result before sending it. Compression artefacts show up in motion, not in a still frame.
Each lossy pass decodes to raw frames and re-compresses from there, so the damage accumulates. Always start from the original file. If you have already lost it, accept the copy you have and compress it once — not repeatedly, hoping it improves.
When the browser tool is the better answer
Three cases, honestly:
- You do not have ffmpeg and will use this once. Installing a video encoder to send one clip is not a good trade.
- The file is sensitive. An upload-based converter puts your footage on somebody's server. This one keeps it in the tab — the encoder is compiled to WebAssembly and runs on your machine.
- You want to see the trade-off before committing. The tool estimates the output size as you move the quality spectrum, which is faster than encoding three times to find out.
Large files are slow either way — this is real encoding work, not a trick — so expect minutes rather than seconds on anything above a few hundred megabytes.
If you only need a different container
Sometimes the file is not too big, it is just the wrong kind of file. Changing the container without touching the video is instant and lossless:
ffmpeg -i input.mov -c copy output.mp4
-c copy means "copy the streams as they are". No quality is lost because
nothing is re-encoded. This only works when the codecs inside are already
compatible with the target container, which for H.264 video and AAC audio they
usually are.