Choosing a codec with full awareness: H.264, H.265/HEVC, VP9, and AV1, mastering the -c:v, -crf, -preset, and -b:v options, understanding the two-pass strategy, and setting resolution, fps, and GOP to balance quality with file size.

After episode 3 you can run your first transcode — format conversion and stream copy — this episode goes into the heart of quality: video encoding. This is where the difference between "playable" results and "production-worthy" results is decided.
You won't memorize all of FFmpeg's options; what you need is the right mental model. Think of encoding like tuning an espresso machine: there are several interrelated parameters, and you must know which to turn first, which to sacrifice, and which should never be touched carelessly.
In episode 0 you learned that a codec is a compression algorithm. Now let's look at the four video codecs you'll encounter most often and their encoders in FFmpeg:
| Codec | FFmpeg Encoder | Characteristics |
|---|---|---|
| H.264 / AVC | libx264 | Widest support, web and mobile standard |
| H.265 / HEVC | libx265 | Better compression, more selective support |
| VP9 | libvpx-vp9 | Open, excels in browsers and YouTube |
| AV1 | libaom-av1, libsvtav1 | Highest compression, slow encoding |
The choice is like choosing a language: H.264 is the universal language understood by all devices; HEVC saves more space but not every player understands it; AV1 is the most economical for the same quality, but needs far more compute power to encode. For general content, H.264 is still the compatibility champion.
Check which encoders are available in your build:
ffmpeg -encoders | grep -E "libx264|libx265|libvpx-vp9|libsvtav1"To see all options of an encoder, run ffmpeg -h encoder=libx264 — the full parameter list with descriptions.
The -c:v option selects the video codec; -c:a for audio. The full command:
ffmpeg -i sample.mp4 -c:v libx264 -crf 18 -preset slow out-h264.mp4ffmpeg -i sample.mp4 -c:v libsvtav1 -crf 30 -preset 8 out-av1.mp4Notice the -crf and -preset pair that always accompanies libx264 — these are the two main levers you must understand.
CRF (Constant Rate Factor) is the most intuitive way to control quality: smaller value = higher quality = bigger file. Its typical scale:
| CRF | Impression |
|---|---|
| 18 | Nearly lossless quality (visually lossless) |
| 23 | libx264 default quality, balanced |
| 28 | Smaller, degradation starts to show |
| 30+ | Small, compromised quality for web |
CRF is constant: FFmpeg adds bitrate in complex scenes and reduces it in calm scenes. Think of it like a cameraman adjusting compression so every moment always looks good — not using one rigid setting for the whole video.
-preset sets the speed vs efficiency trade-off. Slower presets give better compression at the same file size:
| Preset | Direction | Effect |
|---|---|---|
ultrafast, fast | Fast | Larger size |
medium | Balanced | libx264 default |
slow, veryslow | Slow | Smaller size |
For final results that will be stored, -preset slow is usually worth it. For previews or quick tests, use -preset fast. Again: choose according to the situation, not habit.
CRF is great for local files because it chases quality. But for streaming with a specific bitrate target — e.g., max 2 Mbps over a limited network — you need bitrate mode:
ffmpeg -i sample.mp4 -c:v libx264 -b:v 2M -maxrate 2.5M -bufsize 5M out-2mbps.mp4Quality in this mode drops on complex scenes — bitrate is capped, so quality "gives up". For the best results in bitrate mode, use two-pass: the first pass maps the video's complexity, the second pass allocates bitrate optimally:
ffmpeg -y -i sample.mp4 -c:v libx264 -b:v 2M -pass 1 -an -f null /dev/nullffmpeg -i sample.mp4 -c:v libx264 -b:v 2M -pass 2 out-2pass.mp4The first pass only analyzes without producing a video file (directed to -f null /dev/null), then the second pass uses the analysis result. The result: best quality for a given bitrate — the industry standard for bandwidth-targeted distribution.
Besides codec and bitrate, these three settings determine the character of the output video:
| Setting | Option | Function |
|---|---|---|
| Resolution | -vf scale | Change pixel dimensions, e.g., 640x360 |
| Frame rate | -r | Set the output fps |
| GOP | -g | Distance between keyframes (I-frames) |
Combined example: downscale to 480p, keep 30 fps, and GOP 250 (roughly every 8 seconds at 30 fps):
ffmpeg -i sample.mp4 -c:v libx264 -crf 23 -preset slow -vf scale=854:480 -r 30 -g 250 out-480p.mp4GOP matters for streaming: keyframes are the "entry points" for new viewers — too-long GOPs make seeking or stream joins slower. We cover keyframes and streaming in depth in the HLS episode.
All the options above ultimately boil down to one balance: quality vs size. There is no "most correct" setting — it all depends on the goal:
| Scenario | Recommendation |
|---|---|
| Master archive | H.264 CRF 18, preset slow |
| Web distribution | H.264 CRF 23-28, preset medium-slow |
| Limited-bitrate streaming | Two-pass with a -b:v target |
| Space-efficient 4K content | AV1 with libsvtav1 |
Tip
A healthy rule of thumb: keep a master without double encoding (low CRF), and derive from that master. Re-encoding an already-encoded file piles up artifacts — every generation of copy degrades quality, exactly like a photocopy of a photocopy.
In episode 4, you've mastered the video encoding map: choosing H.264, H.265/HEVC, VP9, and AV1 codecs, controlling quality through -crf and -preset, understanding the -b:v bitrate mode and two-pass, and setting resolution, fps, and GOP.
Key takeaways:
-c:v selects the codec; -crf low = high quality = large file.-preset trades speed for efficiency — slow for final results.scale), fps (-r), and GOP (-g) determine the video's character.In the next episode 5, we enter the world of basic filters — scale, crop, rotate, fps, trim, and setpts — along with how to build filter chains with -vf to process video precisely. See you in episode 5!