Skip to content

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

CodecCompressionEncoding speedBrowser supportHardware decodingLicense
H.264100% (baseline)FastAllAll devicesMPEG LA
H.265130-150%MediumSafari, partial Chrome/EdgeModern devicesComplex licensing
AV1150-160%Very slowChrome, Firefox, Edge (recent)Latest devices onlyFree

For codec details, see our H.264 vs H.265 vs AV1 Comparison.

FFmpeg compression commands

bash
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset medium -c:a aac -b:a 128k output.mp4

This is the universal starting point. CRF 23 is the default quality; adjust based on results.

High compression (smaller file)

bash
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)

bash
ffmpeg -i input.mp4 -c:v libx264 -crf 18 -preset slow -c:a aac -b:a 192k output.mp4

H.265 compression (best efficiency)

bash
ffmpeg -i input.mp4 -c:v libx265 -crf 28 -preset medium -c:a aac -b:a 128k output.mp4

H.265 at CRF 28 ≈ H.264 at CRF 23 in quality, but 30-50% smaller.

AV1 compression (modern, future-proof)

bash
# Using SVT-AV1 (faster than libaom)
ffmpeg -i input.mp4 -c:v libsvtav1 -crf 32 -preset 6 -c:a libopus -b:a 128k output.mkv

Two-pass encoding (for fixed bitrate)

bash
# 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.mp4

Useful for streaming with bandwidth limits.

Resolution and frame rate

Downscale for smaller files

bash
# 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.mp4

Reduce frame rate

bash
# 60fps to 30fps
ffmpeg -i input.mp4 -r 30 -c:v libx264 -crf 23 -c:a aac output.mp4

Resolution and frame rate reductions cut file size significantly with minimal perceived quality loss for most content.

Bitrate reference table

ResolutionFrame rateRecommended bitrate (H.264)File size per minute
480p30fps1-1.5 Mbps~10 MB
720p30fps2.5-4 Mbps~25 MB
720p60fps3.5-5 Mbps~35 MB
1080p30fps5-8 Mbps~50 MB
1080p60fps8-12 Mbps~75 MB
4K30fps20-35 Mbps~250 MB
4K60fps35-50 Mbps~400 MB

For H.265, multiply H.264 bitrate by 0.6-0.7 for same quality.

Preset comparison

PresetEncoding speedFile size (same quality)Use case
ultrafast1x1.5-2x largerLive streaming
veryfast1.5x1.3x largerQuick tests
fast2x1.2x largerCasual use
medium (default)3x1.0x (baseline)General use
slow6x0.9x smallerArchival
veryslow12x0.85x smallerFinal delivery
placebo30x+0.83x smallerNot 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:

bash
# 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 96k

For most videos, 128kbps AAC is sufficient. Voice-only content can use 64kbps.

Hardware acceleration

NVIDIA NVENC

bash
ffmpeg -i input.mp4 -c:v h264_nvenc -preset p4 -cq 23 -c:a aac output.mp4

Intel QuickSync

bash
ffmpeg -i input.mp4 -c:v h264_qsv -global_quality 23 -c:a aac output.mp4

AMD AMF

bash
ffmpeg -i input.mp4 -c:v h264_amf -quality balanced -c:a aac output.mp4

Hardware encoders are 5-10x faster than software but produce slightly larger files at the same quality.

Common issues

IssueCauseSolution
File still large after compressionCRF too low or resolution too highUse CRF 28, downscale to 1080p
Quality too poorCRF too highUse CRF 18-23
Encoding too slowPreset too slowUse -preset medium or fast
Audio sync issuesVariable frame rate sourceAdd -vsync 0
File won't playCodec not supportedUse H.264 + AAC in MP4
Encoding errorsInsufficient memoryUse -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 medium or slow preset 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

References

Last updated: