ffmpegh264libx264video-encodingcrfbucket-doc

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

·Javid Jamae·7 min read
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 libx264 selects the H.264 encoder
  • -crf 23 sets quality (lower = better, default 23)
  • -preset medium balances encode speed and compression (default)
  • -c:a aac -b:a 128k re-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 CaseCRF RangeFile Size vs DefaultWhen to Use
Lossless archival010-50x largerSource preservation. Not for delivery.
Visually lossless17-18~2x largerMaster copies, professional editing, archival with compression.
High quality delivery20-22~1.3x largerStreaming to large screens, paid video content.
General purpose23 (default)baselineWeb video, social media, most applications.
Smaller files26-28~50% smallerBandwidth-constrained delivery, batch processing.
Preview / thumbnails30-35~70-80% smallerQuick 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

PresetEncode SpeedFile Size (same CRF)Best For
ultrafast~15x faster~40-50% largerTesting, live previews, CI pipelines
veryfast~8x faster~25% largerReal-time or near-real-time use cases
faster~5x faster~15% largerBatch jobs where speed matters
fast~3x faster~10% largerGood balance for high-volume pipelines
medium1x (baseline)baselineGeneral use (default)
slow~0.5x~5% smallerFinal renders, content you'll serve repeatedly
slower~0.25x~8-10% smallerHigh-value content worth the wait
veryslow~0.1x~10-15% smallerArchival. 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.

Software EngineeringVideo ProcessingFFmpegCloud ArchitectureAPI DesignAutomation

Ready to process videos at scale?

Start using FFmpeg Micro's simple API today. No infrastructure required.

Get Started Free