halfsize / Quality
Compress without losing quality: pick which loss
“Compress without losing quality” is three different requests wearing the same sentence. One of them is free but saves nothing, one is honest but makes the file bigger, and one is what you actually want. The part nobody tells you: quality and size are the same dial.
Three meanings, three outcomes
| What you ask for | What it does | Size | Quality |
|---|---|---|---|
| “Just change the container” | stream copy, no re-encode | same, ±1% | pixel-identical |
| “Lossless” | x264 with -qp 0 | 2–5× larger | pixel-identical |
| “Visually lossless” | CRF 18–20 at source resolution | 40–60% of source | VMAF 95+, same to the eye |
| “Make it fit” | target size, two-pass, resolution stepped down | exactly what you asked | measured, printed, 82–89 typical |
There is no fourth row where the file gets much smaller and the pixels do not change. Compression removes information; the only question is whether the removed information is the part you would have noticed.
Measured on one source, so the numbers mean something
60-second 1080p30 clip at 18 Mbps (136 MB), encoded locally and scored against the original. The caps are measured runs; the CRF row is a typical range, not a single test:
| Mode | Output | Resolution | VMAF | Verdict |
|---|---|---|---|---|
| Original | 136 MB | 1920×1080 | 100 | reference |
| CRF 18, no downscale | ~40–60% of source | 1920×1080 | typically 95+ | visually lossless |
| 20 MB cap | 19.45 MB | 1280×720 | 88.3 | slight softening |
| 10 MB cap | 9.77 MB | 960×540 | 82.9 | soft, motion smears |
| 5 MB cap | 4.93 MB | 640×360 | 72.0 | visible loss |
The interesting part is the cost curve, not any single row. Halving 20 MB to 10 MB costs about five VMAF points; halving again to 5 MB costs another eleven. The first halving is a reasonable trade, the second one is where “looks worse” starts. Spending more bytes has the same curve in reverse: the last few points get very expensive.
Why CRF and “under 20 MB” are different questions
CRF asks “how much can I throw away per frame?” and gives you whatever size falls out. A target size asks “how many bytes per second do I have?” and gives you whatever quality falls out. If a form, an inbox or a chat app is rejecting the file, the second question is the only one that helps, and no amount of tuning CRF will guarantee an answer.
Under the hood the size cap becomes a bitrate: bytes × 8 ÷ seconds − audio − overhead,
then a resolution that can carry that bitrate at roughly 0.072 bits per pixel for H.264
(0.045 for H.265). That second number is why 1080p at 500 kbps looks bad and 540p at 500 kbps
looks fine.
Where quality actually goes
- Resolution — the first thing to spend. A clean smaller frame beats a soft large one.
- Motion — pans, confetti, water and handheld shake eat bitrate faster than faces do.
- Grain and noise — film grain is close to random, so the encoder spends real bits on it. A light denoise before encoding can buy several VMAF points at the same size.
- Audio — 128 kbps costs about 1 MB per minute. Dropping it is free quality for the video.
Check it the honest way: VMAF scores the whole frame, so heavy grain loss can hide in a good average. Watch 10 seconds at 100% zoom on the screen the video will be seen on. If you cannot find the difference there, nobody else will.
The commands
# quality first, size whatever it lands at
$ npx halfsize clip.mp4 --crf 19 --no-downscale
# a hard cap, quality reported afterwards
$ npx halfsize clip.mp4 --to 20mb
# same cap, but keep the frame size
$ npx halfsize clip.mp4 --to 20mb --no-downscale
The FFmpeg equivalent of the first one is -crf 19 -preset slow; the equivalent of the
second is a two-pass run with a computed bitrate, which is what the tool automates. If you want the
raw recipe, see the FFmpeg target-size guide.
When the cap is brutal
A one-hour lecture in 20 MB cannot look good; that is 44 kbps. Options that actually work, in order of how little they hurt: cut the clip to the part that matters, drop the audio and send the slides separately, or accept 360p. Re-encoding it a fourth time will not help.
FAQ
Is zero quality loss possible?
Only without re-encoding. Stream copy keeps every pixel and saves almost nothing; a lossless encode is pixel-exact but several times bigger. Anything smaller than the source is lossy by definition.
What VMAF is “visually lossless”?
93+ at normal viewing distance. 90–93 needs side-by-side frames. Below 85 you see softening in motion and fine texture.
CRF or target size?
CRF when size does not matter. Target size when something rejects the file. Only the second one comes with a guarantee.
Is downscaling worse than a low bitrate?
Usually better. A sharp 540p frame reads as cleaner than a blocky 1080p at the same bitrate.
Can I raise the quality afterwards?
No. Re-encoding a compressed file only adds loss on top of loss. Keep the original until you have the output you want.