Video Compression Complete Guide: From Principles to FFmpeg Practical Use
A 1GB video file can often be compressed to 200MB with no visible quality loss. The trick is understanding how compression works and choosing the right parameters. This guide covers the principles of video compression and provides practical FFmpeg commands for various scenarios.
Why videos can be compressed
Raw video is enormous. One minute of uncompressed 1080p 30fps video is about 6GB. The fact that we can stream 4K movies over 25 Mbps connections is thanks to compression algorithms that exploit three types of redundancy:
1. Spatial redundancy (within a frame)
A blue sky has many pixels of nearly identical color. Instead of storing each pixel, compression stores the color once and references it. This is intra-frame compression (similar to JPEG for images).
2. Temporal redundancy (between frames)
Consecutive frames are usually similar. A talking-head video has the same background for minutes. Compression stores key frames (I-frames) fully and only the differences (P-frames, B-frames) for other frames. This is inter-frame compression.
3. Perceptual redundancy (human vision limits)
Human eyes are more sensitive to brightness than color, and to low frequencies than high frequencies. Compression discards data we can't perceive (chroma subsampling, quantization).
Modern codecs (H.264, H.265, AV1) use all three techniques plus advanced prediction algorithms.
Key concepts
I-frame, P-frame, B-frame
- I-frame (Intra-coded): Complete frame, like a JPEG image
- P-frame (Predictive): Stores only differences from previous frame
- B-frame (Bi-directional): Stores differences from both previous and next frames
A typical GOP (Group of Pictures) is IBBPBBPBBPBB... with one I-frame every 2 seconds.
Bitrate vs CRF
- Bitrate (CBR/VBR): Fixed or variable data rate. Predictable file size but quality varies.
- CRF (Constant Rate Factor): Fixed quality, variable bitrate. Recommended for archival and delivery.
GOP (Group of Pictures)
GOP is the distance between I-frames. For streaming, use 2-second GOP (60 frames at 30fps). For archival, use 10-second GOP for better compression.
Codec comparison
| Codec | Compression | Encoding speed | Browser support | Hardware decoding | License |
|---|---|---|---|---|---|
| H.264 | 100% (baseline) | Fast | All | All devices | MPEG LA |
| H.265 | 130-150% | Medium | Safari, partial Chrome/Edge | Modern devices | Complex licensing |
| AV1 | 150-160% | Very slow | Chrome, Firefox, Edge (recent) | Latest devices only | Free |
For codec details, see our H.264 vs H.265 vs AV1 Comparison.
FFmpeg compression commands
Basic compression (recommended)
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset medium -c:a aac -b:a 128k output.mp4This is the universal starting point. CRF 23 is the default quality; adjust based on results.
High compression (smaller file)
ffmpeg -i input.mp4 -c:v libx264 -crf 28 -preset slow -c:a aac -b:a 96k output.mp4-crf 28: More aggressive compression-preset slow: Better compression efficiency-b:a 96k: Lower audio bitrate
Visually lossless (high quality)
ffmpeg -i input.mp4 -c:v libx264 -crf 18 -preset slow -c:a aac -b:a 192k output.mp4H.265 compression (best efficiency)
ffmpeg -i input.mp4 -c:v libx265 -crf 28 -preset medium -c:a aac -b:a 128k output.mp4H.265 at CRF 28 ≈ H.264 at CRF 23 in quality, but 30-50% smaller.
AV1 compression (modern, future-proof)
# Using SVT-AV1 (faster than libaom)
ffmpeg -i input.mp4 -c:v libsvtav1 -crf 32 -preset 6 -c:a libopus -b:a 128k output.mkvTwo-pass encoding (for fixed bitrate)
# Pass 1
ffmpeg -y -i input.mp4 -c:v libx264 -b:v 5M -pass 1 -an -f mp4 /dev/null
# Pass 2
ffmpeg -i input.mp4 -c:v libx264 -b:v 5M -pass 2 -c:a aac -b:a 128k output.mp4Useful for streaming with bandwidth limits.
Resolution and frame rate
Downscale for smaller files
# 1080p to 720p
ffmpeg -i input.mp4 -vf "scale=-1:720" -c:v libx264 -crf 23 -c:a aac output.mp4
# 4K to 1080p
ffmpeg -i input.mp4 -vf "scale=-1:1080" -c:v libx264 -crf 23 -c:a aac output.mp4Reduce frame rate
# 60fps to 30fps
ffmpeg -i input.mp4 -r 30 -c:v libx264 -crf 23 -c:a aac output.mp4Resolution and frame rate reductions cut file size significantly with minimal perceived quality loss for most content.
Bitrate reference table
| Resolution | Frame rate | Recommended bitrate (H.264) | File size per minute |
|---|---|---|---|
| 480p | 30fps | 1-1.5 Mbps | ~10 MB |
| 720p | 30fps | 2.5-4 Mbps | ~25 MB |
| 720p | 60fps | 3.5-5 Mbps | ~35 MB |
| 1080p | 30fps | 5-8 Mbps | ~50 MB |
| 1080p | 60fps | 8-12 Mbps | ~75 MB |
| 4K | 30fps | 20-35 Mbps | ~250 MB |
| 4K | 60fps | 35-50 Mbps | ~400 MB |
For H.265, multiply H.264 bitrate by 0.6-0.7 for same quality.
Preset comparison
| Preset | Encoding speed | File size (same quality) | Use case |
|---|---|---|---|
| ultrafast | 1x | 1.5-2x larger | Live streaming |
| veryfast | 1.5x | 1.3x larger | Quick tests |
| fast | 2x | 1.2x larger | Casual use |
| medium (default) | 3x | 1.0x (baseline) | General use |
| slow | 6x | 0.9x smaller | Archival |
| veryslow | 12x | 0.85x smaller | Final delivery |
| placebo | 30x+ | 0.83x smaller | Not recommended |
The slow preset is the sweet spot for archival — 2x slower than medium but ~10% smaller files.
Audio compression
Audio is often overlooked but can affect file size:
# Standard quality (recommended)
-c:a aac -b:a 128k
# High quality
-c:a aac -b:a 192k
# Voice only
-c:a aac -b:a 64k
# Maximum compression
-c:a libopus -b:a 96kFor most videos, 128kbps AAC is sufficient. Voice-only content can use 64kbps.
Hardware acceleration
NVIDIA NVENC
ffmpeg -i input.mp4 -c:v h264_nvenc -preset p4 -cq 23 -c:a aac output.mp4Intel QuickSync
ffmpeg -i input.mp4 -c:v h264_qsv -global_quality 23 -c:a aac output.mp4AMD AMF
ffmpeg -i input.mp4 -c:v h264_amf -quality balanced -c:a aac output.mp4Hardware encoders are 5-10x faster than software but produce slightly larger files at the same quality.
Common issues
| Issue | Cause | Solution |
|---|---|---|
| File still large after compression | CRF too low or resolution too high | Use CRF 28, downscale to 1080p |
| Quality too poor | CRF too high | Use CRF 18-23 |
| Encoding too slow | Preset too slow | Use -preset medium or fast |
| Audio sync issues | Variable frame rate source | Add -vsync 0 |
| File won't play | Codec not supported | Use H.264 + AAC in MP4 |
| Encoding errors | Insufficient memory | Use -preset fast |
Summary
Video compression is about finding the right balance between quality and file size. Key takeaways:
- Universal starting command:
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset medium -c:a aac -b:a 128k output.mp4 - Adjust CRF: 18 (visually lossless), 23 (default), 28 (high compression)
- H.265 saves 30-50% over H.264 at same quality
- Downscale resolution for dramatic file size reduction
- Use
mediumorslowpreset for archival
For more FFmpeg commands, see our FFmpeg Getting Started Tutorial.
Quick reference:
- CRF values: 18 (high), 23 (default), 28 (compressed)
- Presets:
medium(general),slow(archival),fast(testing) - H.265 vs H.264: H.265 is 30-50% smaller at same quality
- Hardware encoding: NVENC, QuickSync, AMF for speed