How to Encode Video with H.264 (libx264) Using FFmpeg

H.264 is still the default video codec on the internet. YouTube, Vimeo, Zoom, most browsers, every phone made since 2010. If you're encoding video with FFmpeg and need maximum compatibility, libx264 is the encoder you want.
The trick is picking the right CRF and preset values. Get them wrong and you'll either waste storage on an oversized file or ship a blocky mess your users will notice.
TL;DR
For most web video: -c:v libx264 -crf 23 -preset medium. That's the default for a reason. If you need smaller files, bump CRF to 26-28. If you need higher quality, drop it to 18-20. Slower presets produce smaller files at the same quality but take longer.
What CRF and Preset Do
CRF (Constant Rate Factor) controls quality. It tells FFmpeg "make every frame look this good" and lets the bitrate float to hit that target. Low CRF means high quality and big files. High CRF means lower quality and smaller files.
The libx264 CRF scale runs from 0 (lossless) to 51 (worst). The default is 23.
Preset controls encoding speed. A slower preset spends more CPU time finding better compression, which produces a smaller file at the same quality level. It doesn't improve visual quality. It improves efficiency.
These two settings work independently. CRF picks the quality. Preset picks how efficiently the encoder reaches that quality.
The Basic libx264 Command
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset medium -c:a aac -b:a 128k output.mp4
What each flag does:
-c:v libx264selects the H.264 encoder-crf 23sets quality (lower = better, default 23)-preset mediumbalances encode speed and compression (default)-c:a aac -b:a 128kre-encodes audio to AAC at 128kbps
If your input already has AAC audio and you don't want to re-encode it, use -c:a copy instead.
CRF Values by Use Case
| Use Case | CRF Range | File Size vs Default | When to Use |
|---|---|---|---|
| Lossless archival | 0 | 10-50x larger | Source preservation. Not for delivery. |
| Visually lossless | 17-18 | ~2x larger | Master copies, professional editing, archival with compression. |
| High quality delivery | 20-22 | ~1.3x larger | Streaming to large screens, paid video content. |
| General purpose | 23 (default) | baseline | Web video, social media, most applications. |
| Smaller files | 26-28 | ~50% smaller | Bandwidth-constrained delivery, batch processing. |
| Preview / thumbnails | 30-35 | ~70-80% smaller | Quick previews, quality doesn't matter much. |
A useful rule: every +6 CRF roughly halves the file size. CRF 23 to CRF 29 cuts your file roughly in half. CRF 23 to CRF 17 roughly doubles it.
Don't go above CRF 30 for anything users will actually watch. Compression artifacts become obvious fast.
Preset Speed vs Compression
| Preset | Encode Speed | File Size (same CRF) | Best For |
|---|---|---|---|
| ultrafast | ~15x faster | ~40-50% larger | Testing, live previews, CI pipelines |
| veryfast | ~8x faster | ~25% larger | Real-time or near-real-time use cases |
| faster | ~5x faster | ~15% larger | Batch jobs where speed matters |
| fast | ~3x faster | ~10% larger | Good balance for high-volume pipelines |
| medium | 1x (baseline) | baseline | General use (default) |
| slow | ~0.5x | ~5% smaller | Final renders, content you'll serve repeatedly |
| slower | ~0.25x | ~8-10% smaller | High-value content worth the wait |
| veryslow | ~0.1x | ~10-15% smaller | Archival. Rarely worth it in practice. |
For automation pipelines, medium or fast is usually the right call. Going from medium to veryslow saves maybe 10-15% on file size but takes 10x longer. That math only works if you're encoding once and serving millions of times.
H.264 Profile and Level
libx264 supports three profiles that control which encoding features are used:
- Baseline - no B-frames, no CABAC. Maximum device compatibility (older phones, embedded players). Worst compression.
- Main - adds B-frames and CABAC. Good compression, broad compatibility. Still plays on most hardware from 2012+.
- High - full feature set. Best compression. Default for libx264 and what you should use unless you have a specific device constraint.
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -profile:v high -level 4.1 output.mp4
Level 4.1 supports up to 1080p at 30fps or 720p at 60fps. For 4K, use level 5.1. Most developers don't need to set these manually. libx264 picks sensible defaults based on resolution.
Encoding H.264 via API
If you don't want to install FFmpeg locally or manage encoding infrastructure, you can run the same libx264 command through the FFmpeg Micro API. Same flags, same output. No server to maintain.
curl -X POST https://api.ffmpeg-micro.com/v1/transcodes \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"inputs": [{"url": "https://storage.example.com/input.mp4"}],
"outputFormat": "mp4",
"options": [
{"option": "-c:v", "argument": "libx264"},
{"option": "-crf", "argument": "23"},
{"option": "-preset", "argument": "medium"}
]
}'
The API returns a job ID immediately:
{
"id": "trc_abc123",
"status": "queued",
"outputFormat": "mp4",
"createdAt": "2026-06-17T10:00:00.000Z"
}
Poll GET /v1/transcodes/trc_abc123 until the status is completed, then download the output. FFmpeg Micro handles the infrastructure, codec dependencies, and scaling. You get the same libx264 output without compiling FFmpeg or provisioning servers.
Free tier includes 100 processing minutes. No credit card required.
Common Pitfalls
**Using CRF with -b:v at the same time.** These are conflicting rate control modes. CRF targets constant quality (variable bitrate). -b:v targets constant bitrate. Pick one. If you set both, -b:v wins and CRF gets ignored.
Forgetting the audio codec. If your input has audio in a format incompatible with MP4 (like Vorbis or PCM), FFmpeg will fail or produce a broken file. Always specify -c:a aac or -c:a copy.
Using GPU encoder flags with libx264. NVENC and VideoToolbox are different encoders with different flag sets. -crf doesn't work with NVENC (use -qp instead). If you see "Option crf not found," you're probably using h264_nvenc instead of libx264.
Assuming CRF values are the same across codecs. CRF 23 in libx264 produces different quality than CRF 23 in libx265 or libvpx-vp9. Each codec has its own scale. For H.264, the default is 23. For H.265, it's 28. They produce roughly equivalent quality at those defaults.
FAQ
What CRF value should I use for YouTube uploads?
CRF 18-20. YouTube re-encodes everything, so uploading a higher quality source gives the re-encoder more to work with. Uploading at CRF 28 means YouTube is compressing already-compressed video, which makes the final result worse.
Is libx264 the same as H.264?
H.264 is the codec standard (also called AVC). libx264 is the open-source software encoder that implements that standard. When you run -c:v libx264 in FFmpeg, you're encoding H.264 video using the x264 encoder.
Should I use H.264 or H.265 for web video?
H.264 if you need maximum compatibility (older browsers, older devices, email players). H.265 if your audience is on modern devices and you want 30-50% smaller files. For a detailed H.265 guide, see our libx265 CRF and preset guide.
Can I use two-pass encoding instead of CRF?
Yes. Two-pass targets a specific file size (constant bitrate). CRF targets constant quality (variable file size). Use CRF when quality matters more than file size. Use two-pass when you have a strict size budget.
**What's the difference between -c:v libx264 and -c:v h264_nvenc?**
libx264 is CPU-based and produces the best compression at any given quality level. h264_nvenc uses NVIDIA GPU hardware and is much faster but produces larger files at the same perceived quality. For batch pipelines where speed matters more than file size, NVENC wins. For quality-sensitive encoding, libx264 wins.
*Last verified: 2026-06-17 against FFmpeg 7.x and FFmpeg Micro API v1*
About Javid Jamae
Founder & CEO at FFmpeg Micro
Javid is a software engineer, author, and entrepreneur with over 25 years of professional software development experience across enterprise, startup, and consulting environments. He founded FFmpeg Micro to make video processing accessible to developers through a simple, automation-first REST API.
You might also like

How to Encode H.265 Video with FFmpeg (CRF + Preset Guide)
Learn the right CRF and preset values for FFmpeg libx265 encoding. Includes a decision table, common pitfalls, and how to run H.265 encodes via API.

FFmpeg CRF Explained: Quality vs File Size Guide
Learn how FFmpeg CRF (Constant Rate Factor) controls video quality vs file size. CRF scales for H.264, H.265, VP9, AV1 with recommended settings per use case.

How to Compress Video with FFmpeg Without Losing Quality
Learn how to compress video with FFmpeg using CRF, two-pass encoding, and preset tuning. Reduce file size by 50-80% without visible quality loss.
Ready to process videos at scale?
Start using FFmpeg Micro's simple API today. No infrastructure required.
Get Started Free