If you've ever built a product that handles video uploads, screen recordings, or live streams, you've probably encountered FFmpeg. Most teams start using it for quick conversions and six months later find it running their entire media pipeline.
Once you're in production, you can't just run ffmpeg -i input.mp4 output.webm and walk away. You need to decide which codec plays on which devices. You need to figure out how much CPU time you're burning per video. Sometimes you even need a lawyer to help you understand patent licensing. These choices compound as soon as you add multiple renditions, thumbnails, previews, and device compatibility requirements.
This guide will help you understand the production constraints and tradeoffs so you can make informed decisions about codec selection, hardware acceleration, and licensing.
What FFmpeg is (and why it ends up everywhere)
FFmpeg describes itself as a "complete, cross-platform solution to record, convert and stream audio and video" on the official about page.
In practice, developers rely on:
- CLI tools
ffmpegfor transforming media (convert, encode, filter)ffprobefor inspecting streams, codecs, and metadata
- Libraries (
libavcodec,libavformat,libavfilter, etc.) for embedding media pipelines into applications and services
Production takeaway: FFmpeg is powerful because it's format-agnostic—ideal for ingest pipelines where you don't control what users upload.
Containers vs codecs (the most common issue in production)
This distinction trips people up constantly. A container like MP4 or MKV is just the wrapper around your video. The actual video and audio data uses a codec like H.264 or VP9. You can have a perfectly valid MP4 file that refuses to play anywhere because the codec inside is obscure or unsupported. Mozilla's guide on media containers is one of the clearest public references on how containers and codecs fit together.
Quick reference: containers in the real world
| Container | Strength | Common codec pairings | Practical risk |
|---|---|---|---|
| MP4 | Broad device/browser compatibility | H.264/H.265 + AAC | People assume "MP4 always plays"; it doesn't if streams are unusual |
| MKV (Matroska) | Flexible for ingest/archival | Almost anything | Often needs conversion for web/mobile playback |
| WebM | Web-focused | VP9/AV1 + Opus | Support varies by codec + device generation |
| MPEG-TS | Transport / streaming | H.264/H.265 + AAC | Great for streaming; not ideal as a download format |
For browser-centric constraints, see MDN's video codec guide.
Codec choice is a four-way tradeoff
Picking a codec involves more than just video quality. You're making simultaneous tradeoffs between how many devices can play it back, how much bandwidth and storage it consumes, how long encoding takes, and whether you need to worry about patent licensing.
FFmpeg's AV1 guide notes that AV1 is typically more efficient than older codecs—often cited as roughly ~30% better than VP9 and ~50% better than H.264 in relevant scenarios (FFmpeg Wiki: Encode/AV1).
"We've seen file size reductions of 20-40% when moving from VP9 to AV1 for the same perceptual quality." — Netflix Tech Blog on AV1 deployment (2021)
Codec decision matrix
| Codec | Compatibility | Compression efficiency | Software encode cost | Licensing reality |
|---|---|---|---|---|
| H.264 (AVC) | Very high | Medium | Low—Medium | Patent licensed in many contexts (example pool: Via LA AVC/H.264) |
| H.265 (HEVC) | High but uneven | High | High | Licensing can be complex (examples: Access Advance HEVC, Via LA HEVC/VVC) |
| VP9 | High on modern web | High | High | Generally treated as royalty-free in many contexts (verify for your use case) |
| AV1 | Growing | Very high | Very high | Positioned as royalty-free by AOMedia |
Real-world encoding speeds (1080p30 content)
| Codec | Relative speed (vs H.264) | Source |
|---|---|---|
| H.264 (x264 medium) | 1.0x baseline | Industry standard |
| H.265 (x265 medium) | 0.3-0.5x | ~2-3x slower |
| VP9 | 0.2-0.4x | 2.5-5x slower |
| AV1 (libaom) | 0.02-0.1x | 10-50x slower |
Encoding rate control: CRF, presets, and predictable output
For x264 (H.264), FFmpeg's official guide recommends two commonly used approaches: CRF (quality-based) and two-pass ABR (bitrate/size-targeted) (FFmpeg Wiki: Encode/H.264).
Rate control options
| Mode | Best for | What you control | What you trade off |
|---|---|---|---|
| CRF | General UGC encoding | Perceptual quality target | Output bitrate/size varies by content |
| 2-pass ABR | Predictable bitrate/size | Average bitrate target | More compute; may vary per-scene quality |
"For most use cases, CRF is the recommended rate control mode. It provides the best quality per bit, and unlike target bitrate encoding, every frame gets the bits it deserves." — Handbrake's video encoding settings guide
Default (H.264 + AAC, CRF-based):
1ffmpeg -i input.mp4 -c:v libx264 -preset medium -crf 23 -c:a aac -b:a 128k output.mp4
For deeper intuition about CRF, see slhck's CRF guide.
Hardware acceleration
FFmpeg's canonical intro is HWAccelIntro.
| Backend | Typical environment | Why teams use it |
|---|---|---|
| NVENC/NVDEC | NVIDIA GPUs | High throughput, lower CPU |
| Intel QSV | Intel iGPU / servers | Dense transcode capacity |
| VideoToolbox | macOS/iOS | Apple ecosystem support |
| VAAPI | Linux | Multi-vendor support |
"Hardware encoders trade some quality for speed. For user-generated content where encode time matters more than squeezing out the last bit of efficiency, hardware acceleration is often the right call." — FFmpeg Hardware Acceleration Guide
Throughput example: 1080p → 720p H.264 transcoding
| Method | Streams per server | Cost efficiency |
|---|---|---|
| CPU (16-core Xeon) | 4-6 simultaneous | Baseline |
| NVENC (single RTX 4000) | 15-20 simultaneous | ~3-4x throughput |
| NVENC (8x T4 GPUs) | 120-160 simultaneous | Dense cloud transcode |
Media economics
Cloudflare explains why video is economically different from typical web assets in its overview of delivering videos.
| Output | Why it exists |
|---|---|
| 360p | Poor networks, low-end devices |
| 720p | Default playback quality |
| 1080p+ | Large screens / premium quality |
Storage impact example (60-minute 1080p video)
| Codec @ similar quality | Approximate file size | Monthly storage cost (at $0.023/GB) |
|---|---|---|
| H.264 | ~2.5 GB | $0.058 |
| H.265 | ~1.5 GB | $0.035 |
| AV1 | ~1.2 GB | $0.028 |
For a platform with 100,000 hours of content, AV1 vs H.264 could mean ~$2,300/month in storage savings.
Licensing
FFmpeg licensing is documented on the project's Legal page and its LICENSE doc. Codec patent licensing is separate (examples: Via LA AVC/H.264, Access Advance HEVC). AV1 is positioned as royalty-free by the Alliance for Open Media.
What good production FFmpeg looks like
- Inspect first with
ffprobe - Be explicit with codecs/containers/settings
- Measure encode time, output size, and playback failures
FAQs
These FAQs cover the most common questions developers ask when moving FFmpeg from experimentation to production.
-
What is FFmpeg?
FFmpeg is a toolkit for recording, converting, filtering, and streaming audio/video, described on the official site as a "complete, cross-platform solution to record, convert and stream audio and video" (FFmpeg About). -
How to use FFmpeg to convert MKV to MP4
If streams are compatible, stream copy:bash1ffmpeg -i input.mkv -c copy output.mp4If needed, map all streams:
bash1ffmpeg -i input.mkv -map 0 -c copy output.mp4If it fails, it's usually container/codec mismatch—see MDN containers.
-
How to convert WebM to MP4 using FFmpeg
Inspect:bash1ffprobe -hide_banner -i input.webmEncode:
bash1ffmpeg -i input.webm -c:v libx264 -preset medium -crf 23 -c:a aac -b:a 128k output.mp4References: FFmpeg Encode/H.264, MDN codecs.
-
What is CRF in FFmpeg?
CRF is quality-based rate control recommended in FFmpeg Encode/H.264. Deeper explanation: slhck CRF guide. -
How to set bitrate in FFmpeg
bash1ffmpeg -i input.mp4 -c:v libx264 -b:v 2500k -c:a aac -b:a 128k output.mp4See also two-pass ABR in FFmpeg Encode/H.264.
-
FFmpeg default audio codec when converting to MP4
Check:bash1ffmpeg -h muxer=mp4Reference discussion: Stack Overflow muxer defaults. AAC notes: FFmpeg Encode/AAC.
-
Why doesn't FFmpeg support feature [xyz]?
See the official FFmpeg FAQ. -
I cannot read this file although this format seems to be supported by FFmpeg
This is commonly container/codec mismatch—see the FFmpeg FAQ. Debug:bash12ffprobe -hide_banner -i input_file ffmpeg -v error -i input_file -f null - -
Are there examples illustrating how to use the FFmpeg libraries?
Start with Using libav* and the ffmpeg-codecs docs.