Last updated: August 11

<span aria-hidden="true" id="how-to-compress-video-with-ffmpeg"></span>

# How to compress video with FFmpeg

![Kevin van Zonneveld](/assets/images/teammates/avatar-kvz-4.jpg?dpl=dpl_BnUJZFhrwex1Jq8Abt73kPZ9xPzJ)

#### Kevin van Zonneveld

Co-founder · Amsterdam, The Netherlands · Show bio

[](https://x.com/kvz)[](https://github.com/kvz)

Optimizing video content for fast loading times is crucial for modern web applications. Large video files can significantly impact website performance, affecting user experience and search engine rankings. FFmpeg, a powerful open-source multimedia framework, offers robust tools to compress videos while maintaining quality, leading to faster load times and improved user engagement.

For a compatible MP4 with a good quality-to-size balance, start with:

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

```

Increase CRF for a smaller file or decrease it for higher quality. A slower preset usually improves compression efficiency but takes longer to encode. Always compare the result with representative source footage before applying one setting to a whole library.

<span aria-hidden="true" id="understanding-video-codecs-and-formats"></span>

## Understanding video codecs and formats

For web video, select codecs based on compatibility and compression efficiency:

* H.264: Offers universal compatibility and is ideal for general use.
* H.265: Delivers approximately 30% better compression than H.264 and is supported on most modern devices.
* VP9: Provides a free alternative to H.265 with wide browser support.
* AV1: Provides the best compression with growing support, making it a future-proof choice.

A codec encodes and decodes digital video data. Container formats (such as MP4, MKV, or WebM) package video, audio, and metadata together. For web delivery, MP4 with H.264 is the most compatible option, while WebM with VP9 or AV1 can offer superior compression for supported browsers.

|Codec|Compression|Browser Support|Use Case|
|-|-|-|-|
|H.264|Good|Universal|General use|
|H.265|\~30% more efficient|Partial|Modern devices|
|VP9|Efficient|Wide|Free alternative|
|AV1|Best|Growing|Future-proof|

<span aria-hidden="true" id="installing-ffmpeg-on-your-system"></span>

## Installing FFmpeg on your system

The examples use options available in current FFmpeg releases. Check `ffmpeg -version` and the encoders included in your build before selecting a codec.

<span aria-hidden="true" id="linux-ubuntudebian"></span>

### Linux (Ubuntu/Debian)

```bash
sudo apt update && sudo apt install ffmpeg

```

<span aria-hidden="true" id="macos"></span>

### macOS

```bash
brew install ffmpeg

```

<span aria-hidden="true" id="windows"></span>

### Windows

1. Download the latest build from [gyan.dev⁠](https://www.gyan.dev/ffmpeg/builds/).
2. Extract the archive.
3. Add the `bin` folder to your system's PATH.

<span aria-hidden="true" id="basic-video-compression-with-ffmpeg"></span>

## Basic video compression with FFmpeg

<span aria-hidden="true" id="reducing-video-file-size"></span>

### Reducing video file size

The following command provides a good balance between quality and compression for web video using H.264:

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

```

Recommended CRF values by codec:

* H.264: 18-23 for high quality, 23-28 for general use
* H.265: 24-30 (roughly equivalent to H.264 at CRF 18-24)
* VP9: 15-35 (using a different scale)
* AV1: 25-35 for general use

<span aria-hidden="true" id="modern-codec-options"></span>

### Modern codec options

For browsers supporting newer codecs, you can use AV1 for improved compression:

```bash
ffmpeg -i input.mp4 -c:v libaom-av1 -crf 30 -b:v 0 -strict experimental -cpu-used 8 -row-mt 1 -c:a libopus -b:a 128k output.mkv

```

<span aria-hidden="true" id="advanced-compression-techniques-with-ffmpeg"></span>

## Advanced compression techniques with FFmpeg

<span aria-hidden="true" id="two-pass-encoding"></span>

### Two-pass encoding

For precise bitrate control, use two-pass encoding:

```bash
# First pass
ffmpeg -y -i input.mp4 -c:v libx264 -b:v 1000k -pass 1 -an -f null /dev/null

# Second pass
ffmpeg -i input.mp4 -c:v libx264 -b:v 1000k -pass 2 -c:a aac -b:a 128k output.mp4

```

<span aria-hidden="true" id="quality-based-encoding"></span>

### Quality-based encoding

To maintain consistent visual quality, consider quality-based encoding:

```bash
# H.265 (HEVC)
ffmpeg -i input.mp4 -c:v libx265 -crf 28 -preset medium -tag:v hvc1 -c:a aac -b:a 128k output.mp4

# Vp9
ffmpeg -i input.mp4 -c:v libvpx-vp9 -b:v 0 -crf 30 -row-mt 1 -c:a libopus -b:a 128k output.webm

```

<span aria-hidden="true" id="browser-compatibility"></span>

## Browser compatibility

|Codec|Chrome|Firefox|Safari|Edge|
|-|-|-|-|-|
|H.264|✅|✅|✅|✅|
|H.265|⚠️ (partial)|❌|✅|⚠️ (partial)|
|VP9|✅|✅|⚠️ (Safari v16+)|✅|
|AV1|✅|✅|⚠️ (Safari v17+)|✅|

<span aria-hidden="true" id="comparing-quality-and-file-size"></span>

## Comparing quality and file size

Use FFmpeg's built-in tools to evaluate your output:

```bash
# Preview video
ffplay output.mp4

# Compare file sizes
ls -lh input.mp4 output.mp4

# Get detailed video information
ffprobe -v quiet -print_format json -show_format -show_streams output.mp4

```

<span aria-hidden="true" id="automating-batch-video-compression"></span>

## Automating batch video compression

<span aria-hidden="true" id="bash-script"></span>

### Bash script

```bash
#!/bin/bash

input_dir="/path/to/videos"
output_dir="/path/to/output"

mkdir -p "$output_dir"

for file in "$input_dir"/*.mp4; do
  filename=$(basename "$file")
  ffmpeg -i "$file" \
    -c:v libx264 \
    -crf 23 \
    -preset medium \
    -movflags +faststart \
    -c:a aac \
    -b:a 128k \
    "$output_dir/${filename%.*}_compressed.mp4"
done

```

<span aria-hidden="true" id="powershell-script"></span>

### Powershell script

```powershell
$inputDir = "C:\path\to\videos"
$outputDir = "C:\path\to\output"

New-Item -ItemType Directory -Force -Path $outputDir

Get-ChildItem -Path $inputDir -Filter *.mp4 | ForEach-Object {
    $outputFile = Join-Path $outputDir ($_.BaseName + "_compressed.mp4")
    ffmpeg -i $_.FullName `
        -c:v libx264 `
        -crf 23 `
        -preset medium `
        -movflags +faststart `
        -c:a aac `
        -b:a 128k `
        $outputFile
}

```

<span aria-hidden="true" id="best-practices"></span>

## Best practices

* Choose codecs based on your target audience and browser support requirements.
* Test different CRF values to determine the optimal balance between quality and file size.
* Use two-pass encoding for more predictable file sizes.
* Enable fast start to improve web playback performance.
* Consider generating multiple formats to ensure compatibility across devices.

In summary, FFmpeg offers a versatile and powerful solution for video compression for the web. By carefully selecting codecs and fine-tuning your encoding parameters, you can optimize video performance without compromising quality.

For automated video processing at scale, consider using Transloadit's video encoding service, which provides optimized encoding pipelines and automatic format selection based on browser capabilities.

\#ffmpeg#video-compression#reduce-video-file-size#video-optimization-for-web#ffmpeg-command-line#video-codecs#batch-video-compression#video-encoding-service

### 👩‍💻 Join 20k+ developers

Sign up for our [monthly newsletter](/newsletters.md) to receive direct links to 3 exclusive tech — and 2 product updates. No less, no more.

Your email:

Get access

## File uploading and encoding. Made simple.

Transloadit streamlines file handling for developers, trusted by brands like Coursera and The New York Times. We’re known for a reliable API, top-notch support, and a strong commitment to open source, with projects like [Uppy⁠](https://uppy.io) and [Tus⁠](https://tus.io) setting standards in file processing.

[Sign up](/c/)[Book a Demo](https://survey.typeform.com/to/kRg47Xi5)

No credit card needed · 5 GB included in the free plan

Cancel anytime
