CLI AI

Compress a video to MP4 with ffmpeg

2026-06-03

ffmpeg -i in.mp4 -c:v libx264 -crf 28 -preset fast out.mp4 compresses a video to MP4, trading a bit of quality for a much smaller file — CRF is the dial, and 18–28 is the only range worth remembering. This also covers the CRF scale in real numbers, batch-converting a folder, and the step most guides skip: checking duration and codecs before an hour-long re-encode.

1. What's actually inside the file

clai
$ clai show me the duration of this video→ ffprobe -v error -show_entries format=duration -of csv=p=0 in.mp42.000000

ffprobe ships with ffmpeg and doesn't re-encode anything. Before you start a conversion that might run for an hour, look at what you're actually working with.

2. Compress it, controlling quality

clai
$ clai compress this video, quality matters more than size→ ffmpeg -i in.mp4 -c:v libx264 -crf 28 -preset fast out.mp4

On the test clip, the source was 13074 bytes and the output came out at 10861 bytes. CRF is a quality scale from 0 to 51, where lower means better and bigger. The range worth knowing is 18–28: 18 is visually indistinguishable from the source, 23 is a solid default, 28 is noticeably softer but still fine for most uses.

3. Shrink the resolution when compression alone isn't enough

clai
$ clai compress it harder and scale the height down to 144 pixels→ ffmpeg -i in.mp4 -vf "scale=-2:144" -crf 30 small.mp4

Same clip, now 8130 bytes against the original 13074. The -2 in the width means "work it out yourself, keep the aspect ratio, and round to an even number" — codecs require even dimensions, and that's exactly where half the ffmpeg one-liners online fall over.

4. Change the container without touching the content

clai
$ clai move this video from mov to mp4 without re-encoding→ ffmpeg -i input.mov -c copy output.mp4

-c copy copies the streams as they are — seconds instead of minutes, no quality loss, as long as the codecs are compatible with the new container. For mov to mp4, they usually are.

5. Process an entire folder

clai
$ clai convert every mov in this folder to mp4, keep the names→ for f in *.mov; do ffmpeg -i "$f" -c:v libx264 -crf 23 "${f%.mov}.mp4"; done

${f%.mov} strips the extension. The quotes around $f aren't optional — skip them and the first filename with a space in it breaks the loop.

6. Cut a clip without re-encoding

clai
$ clai cut a one-minute clip starting at 30 seconds→ ffmpeg -ss 30 -i input.mp4 -t 60 -c copy clip.mp4

-ss before -i is fast because ffmpeg seeks instead of decoding. With -c copy the cut lands on the nearest keyframe, so the start can drift by up to a second. For frame accuracy, drop -c copy and pay for the re-encode.

Gotchas

  • -preset changes speed, not quality. ultrafast encodes fast into a bigger file, slow does the opposite. At the same CRF it barely affects quality.
  • Audio gets re-encoded silently. If you don't mention -c:a, ffmpeg decides for you. Add -c:a copy when the audio doesn't need touching.
  • CRF doesn't mean the same thing across codecs. For libx265, the same number buys more quality: CRF 28 on x265 is roughly CRF 23 on x264.

Related questions

Which CRF should I use? Start at 23. File too big — go to 28. Archiving something that shouldn't degrade — use 18.

Why is ffmpeg better than an online converter? The clip never leaves your machine, there's no size cap, and one command handles a whole folder.

How do I speed up encoding? Use a hardware encoder: -c:v h264_nvenc on NVIDIA, -c:v h264_videotoolbox on macOS. Much faster, slightly worse quality at the same bitrate.

See also

CliAI writes the right ffmpeg flags for whatever you describe, CRF and scale filter included. Install it in one line.