What does FFmpeg have to do with digital minimalism? I think it does A lot. Do you use an application for screen capturing? Streaming? Screenshots? To convert videos, extract audio, change dimensions or frame rate, etc... There's a very high chance that under the hood your tool FFmpeg is the one doing the actual work. It's amazing how many tools rely on this "simple" open-source, command-line solution.
It may feel intimidating at first, but this unlocks an entirely new level of freedom and potential automations. Leading AI models know it very well, so if you're lazy like me, you can just ask for a command that does what you need and skip the learning curve...
If you want to dig a little deeper - here's a complete FFmpeg tutorial/manual!
Installation Instructions
Latest FFmpeg Version Information (2025)
- Latest Stable: FFmpeg 8.0 "Huffman" (August 2025)
- Previous Stable: FFmpeg 7.1.1 (March 2025)
- Recommendation: Use git master builds for the latest features and active maintenance
Windows Installation
Method 1: Manual Installation (Recommended)
Download and Setup:
- Visit gyan.dev builds for the most popular Windows builds
- Choose your build type:
- Release Essentials (27MB): Basic use, common codecs
- Release Full: Advanced use, additional codecs
- Git Master: Daily builds with latest features
Installation Steps:
:: Create directory
mkdir C:\ffmpeg
:: Extract downloaded files to C:\ffmpeg\
:: Your folder structure should be: C:\ffmpeg\bin\ffmpeg.exe
Add to PATH (Windows):
# Via PowerShell (Administrator)
$ffmpeg = 'C:\ffmpeg\bin'
$path = [Environment]::GetEnvironmentVariable('Path', 'Machine').TrimEnd([Char]';')
[Environment]::SetEnvironmentVariable("Path", "$path;$ffmpeg", 'Machine')
# Verify installation
ffmpeg -version
Method 2: Package Managers
# Chocolatey
choco install ffmpeg # Essentials
choco install ffmpeg-full # Full build
# Winget
winget install "FFmpeg (Essentials Build)"
# Scoop
scoop install ffmpeg
scoop install ffmpeg-gyan-nightly # Git master builds
macOS Installation
Homebrew (Recommended)
# Install Homebrew (if not installed)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Install FFmpeg
brew update
brew install ffmpeg
# With additional codecs
brew tap homebrew-ffmpeg/ffmpeg
brew install homebrew-ffmpeg/ffmpeg/ffmpeg --with-fdk-aac --with-librsvg
# Git master version
brew install ffmpeg --HEAD
# Update FFmpeg
brew update && brew upgrade ffmpeg
Static Build (Manual)
# Download from EverMeet
curl -O https://evermeet.cx/ffmpeg/ffmpeg-latest.zip
unzip ffmpeg-latest.zip
sudo cp ffmpeg /usr/local/bin/
sudo chmod +x /usr/local/bin/ffmpeg
# Verify installation
ffmpeg -version
Linux Installation
Debian/Ubuntu
# Update and install
sudo apt update
sudo apt install ffmpeg
# For latest version
sudo add-apt-repository ppa:savoury1/ffmpeg4
sudo apt update && sudo apt install ffmpeg
# Via Snap (latest version)
sudo snap install ffmpeg
Fedora/CentOS/RHEL
# Enable RPM Fusion
sudo dnf install -y https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm
sudo dnf install -y https://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm
# Install FFmpeg
sudo dnf install ffmpeg ffmpeg-devel
Static Build (All Linux)
# Download and install
wget https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz
tar -xf ffmpeg-release-amd64-static.tar.xz
sudo cp ffmpeg-*-static/ffmpeg /usr/local/bin/
sudo cp ffmpeg-*-static/ffprobe /usr/local/bin/
sudo chmod +x /usr/local/bin/ffmpeg /usr/local/bin/ffprobe
Build Types and Codec Support
- Static Builds: Self-contained, no dependencies, larger files
- Shared Builds: Smaller executable, requires separate libraries
- Essentials: H.264, H.265, VP9, AAC, MP3, common formats
- Full: Additional codecs, including ProRes, DNxHD,and specialized filters
Basic Concepts and Terminology
Core Concepts
Containers vs Codecs
Container: Wrapper format combining multiple streams
- MP4: Universal compatibility, H.264/H.265 + AAC
- MKV: Highly flexible, supports any codec
- WebM: Open format, VP8/VP9 + Opus only
- AVI: Legacy format with broad compatibility
Video Codecs: Compression algorithms for video
- H.264 (libx264): Most widely supported, good compression
- H.265 (libx265): Better compression, less compatibility
- VP9: Open-source alternative to H.265
- AV1: Next-generation codec, excellent compression
Audio Codecs: Compression algorithms for audio
- AAC: Modern, efficient, widely supported
- MP3: Legacy but universal compatibility
- Opus: Superior quality at low bitrates
- FLAC: Lossless compression for archival
Streams and Stream Mapping
Stream Types:
- Video (v): Visual content
- Audio (a): Sound content
- Subtitle (s): Text overlays
- Data (d): Metadata or other data
Stream Specifiers:
0:0 # First stream of first input
0:v:0 # First video stream of first input
0:a:1 # Second audio stream of first input
Quality Control Parameters
Video Quality:
- CRF (Constant Rate Factor): 0-51 scale, lower = better quality
- H.264: 18-28 range (23 default)
- H.265: 20-30 range (28 default)
- Bitrate: Fixed bitrate in bits per second (e.g.,
2M
= 2 Mbps)
Audio Quality:
- Sample Rate:
-ar 44100
(CD quality),-ar 48000
(high quality) - Bitrate:
-b:a 128k
(good),-b:a 320k
(high quality) - Channels:
-ac 2
(stereo),-ac 1
(mono)
Command Structure and Syntax
Basic Command Structure
ffmpeg [global_options] {[input_options] -i input} ... {[output_options] output} ...
Key Principles:
- Options apply to the next specified file
- Order matters: input options before
-i
, output options before output filename - Multiple inputs/outputs supported with separate option sets
Essential Global Options
-y # Overwrite output files without asking
-hide_banner # Suppress startup information
-loglevel quiet # Suppress all output except errors
-stats # Show encoding progress
-threads 0 # Auto-detect optimal thread count
Basic Examples
# Simple format conversion
ffmpeg -i input.mp4 output.avi
# With options
ffmpeg -y -hide_banner -i input.mp4 -c:v libx264 -crf 23 -c:a aac output.mp4
# Multiple inputs/outputs
ffmpeg -i input1.mp4 -i input2.mp4 -c copy output1.mkv -c:v libx264 output2.mp4
File Format Conversion
Common Video Conversions
MKV to MP4 (Stream Copy - Fastest)
# Windows CMD
ffmpeg -i input.mkv -c copy output.mp4
# macOS Terminal
ffmpeg -i input.mkv -c copy output.mp4
# Linux Bash
ffmpeg -i input.mkv -c copy output.mp4
MKV to MP4 (Re-encode for Compatibility)
# All Platforms
ffmpeg -i input.mkv -c:v libx264 -crf 23 -c:a aac -movflags +faststart output.mp4
WebM to MP4 (High Quality)
# All Platforms
ffmpeg -i input.webm -c:v libx264 -preset slow -crf 22 -c:a aac -b:a 128k output.mp4
MOV to MP4 (Usually Stream Copy)
# All Platforms
ffmpeg -i input.mov -c copy output.mp4
Audio Format Conversions
Extract Audio to MP3
# Windows
ffmpeg -i input.mp4 -vn -c:a libmp3lame -b:a 192k output.mp3
# macOS/Linux
ffmpeg -i input.mp4 -vn -c:a libmp3lame -b:a 192k output.mp3
Convert to Different Audio Formats
# To AAC (M4A)
ffmpeg -i input.wav -c:a aac -b:a 256k output.m4a
# To FLAC (Lossless)
ffmpeg -i input.wav -c:a flac -compression_level 12 output.flac
# To Opus (Modern Codec)
ffmpeg -i input.wav -c:a libopus -b:a 128k output.opus
Batch Conversion Scripts
Windows PowerShell
# Convert all MKV files to MP4
Get-ChildItem *.mkv | ForEach-Object {
$outputFile = $_.BaseName + ".mp4"
& ffmpeg -i $_.Name -c copy $outputFile
Write-Host "Converted: $($_.Name)"
}
macOS/Linux Bash
#!/bin/bash
# Convert all MKV files to MP4
for file in *.mkv; do
if [[ -f "$file" ]]; then
output="${file%.*}.mp4"
ffmpeg -i "$file" -c copy "$output"
echo "Converted: $file"
fi
done
Video Processing Operations
Scaling and Resolution Changes
Basic Scaling
# Scale to specific resolution
ffmpeg -i input.mp4 -vf "scale=1280:720" output.mp4
# Maintain aspect ratio (auto height)
ffmpeg -i input.mp4 -vf "scale=1280:-1" output.mp4
# Scale by percentage
ffmpeg -i input.mp4 -vf "scale=iw*0.5:ih*0.5" output.mp4
High-Quality Scaling
# Upscaling with Lanczos algorithm
ffmpeg -i input.mp4 -vf "scale=3840:2160:flags=lanczos" -c:v libx264 -crf 18 output.mp4
# Force aspect ratio with letterboxing
ffmpeg -i input.mp4 -vf "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2" output.mp4
Cropping Videos
Fixed Dimension Cropping
# Basic crop: width:height:x:y
ffmpeg -i input.mp4 -vf "crop=640:480:100:50" output.mp4
# Center crop
ffmpeg -i input.mp4 -vf "crop=640:480:(main_w-640)/2:(main_h-480)/2" output.mp4
# Remove black bars (crop sides)
ffmpeg -i input.mp4 -vf "crop=ih*16/9:ih" output.mp4
Automatic Black Border Detection
# Detect crop parameters
ffmpeg -i input.mp4 -vf cropdetect -f null -
# Apply detected crop (example output from detection)
ffmpeg -i input.mp4 -vf "crop=1072:1072:4:424" output.mp4
Rotation and Flipping
Rotation
# Rotate 90 degrees clockwise
ffmpeg -i input.mp4 -vf "transpose=1" output.mp4
# Rotate 90 degrees counter-clockwise
ffmpeg -i input.mp4 -vf "transpose=2" output.mp4
# Rotate 180 degrees
ffmpeg -i input.mp4 -vf "transpose=2,transpose=2" output.mp4
# Arbitrary angle rotation
ffmpeg -i input.mp4 -vf "rotate=PI/4:fillcolor=black" output.mp4
Flipping
# Horizontal flip (mirror)
ffmpeg -i input.mp4 -vf "hflip" output.mp4
# Vertical flip
ffmpeg -i input.mp4 -vf "vflip" output.mp4
# Both flips (equivalent to 180° rotation)
ffmpeg -i input.mp4 -vf "hflip,vflip" output.mp4
Video Cutting and Trimming
Time-Based Cutting
# Cut from 10 seconds, duration 30 seconds
ffmpeg -i input.mp4 -ss 10 -t 30 -c copy output.mp4
# Cut from 1:30 to 2:45
ffmpeg -i input.mp4 -ss 00:01:30 -to 00:02:45 -c copy output.mp4
# Cut last 10 minutes
ffmpeg -sseof -600 -i input.mp4 -c copy output.mp4
Frame-Accurate Cutting
# Accurate seeking (slower but precise)
ffmpeg -i input.mp4 -ss 10 -t 30 -avoid_negative_ts make_zero -fflags +genpts output.mp4
# Re-encode for frame accuracy
ffmpeg -i input.mp4 -ss 10 -t 30 -c:v libx264 -c:a copy output.mp4
Audio Processing
Volume Control and Normalization
Basic Volume Adjustment
# Increase volume by 3dB
ffmpeg -i input.mp4 -af "volume=3dB" output.mp4
# Decrease volume by 50%
ffmpeg -i input.mp4 -af "volume=0.5" output.mp4
# Set specific volume level
ffmpeg -i input.mp4 -af "volume=2.0" output.mp4
Professional Audio Normalization
# EBU R128 Loudness Normalization (Recommended)
# Two-pass for best results
ffmpeg -i input.wav -af loudnorm=I=-16:LRA=11:tp=-1.5:print_format=json -f null -
# Apply with measured values from first pass
ffmpeg -i input.wav -af loudnorm=I=-16:LRA=11:tp=-1.5:measured_I=-23.01:measured_tp=-10.11:measured_LRA=18.80 output.wav
# Dynamic normalization (single pass)
ffmpeg -i input.wav -af "dynaudnorm=p=0.9:s=5" output.wav
Channel Manipulation
# Convert stereo to mono
ffmpeg -i stereo.wav -ac 1 mono.wav
# Extract left channel only
ffmpeg -i stereo.wav -af "pan=mono|c0=0.5*c0" left_only.wav
# Extract right channel only
ffmpeg -i stereo.wav -af "pan=mono|c0=0.5*c1" right_only.wav
# Swap left and right channels
ffmpeg -i input.wav -af "pan=stereo|c0=c1|c1=c0" output.wav
Audio Filtering and Enhancement
Noise Reduction
# FFT-based noise reduction
ffmpeg -i noisy_audio.wav -af "afftdn=nr=12:nf=-25" clean_audio.wav
# High/low pass filtering
ffmpeg -i input.wav -af "highpass=f=80" output.wav # Remove rumble
ffmpeg -i input.wav -af "lowpass=f=8000" output.wav # Remove hiss
Equalization
# Parametric EQ - boost 1kHz by 5dB
ffmpeg -i input.wav -af "equalizer=f=1000:width_type=o:width=2:g=5" output.wav
# Multi-band EQ
ffmpeg -i input.wav -af "equalizer=f=100:g=3,equalizer=f=1000:g=-2,equalizer=f=5000:g=1" output.wav
Dynamic Range Compression
# Basic compression
ffmpeg -i input.wav -af "acompressor=threshold=0.05:ratio=4:attack=200:release=1000" compressed.wav
# Noise gate (remove quiet background noise)
ffmpeg -i input.wav -af "agate=threshold=0.1:attack=50:release=50" output.wav
Advanced Video Editing
Video Concatenation and Merging
Same Format Concatenation (Fast)
# Create file list
echo "file 'video1.mp4'" > files.txt
echo "file 'video2.mp4'" >> files.txt
echo "file 'video3.mp4'" >> files.txt
# Concatenate without re-encoding
ffmpeg -f concat -safe 0 -i files.txt -c copy output.mp4
Different Format Concatenation
# Two different formats with complex filter
ffmpeg -i input1.mp4 -i input2.wmv -filter_complex "[0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1[outv][outa]" -map "[outv]" -map "[outa]" output.mp4
# Scale videos before concatenating
ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex "[0:v]scale=1920:1080[v0];[1:v]scale=1920:1080[v1];[v0][0:a][v1][1:a]concat=n=2:v=1:a=1[outv][outa]" -map "[outv]" -map "[outa]" output.mp4
Multi-Layout Arrangements
# Side-by-side
ffmpeg -i left.mp4 -i right.mp4 -filter_complex "[0:v][1:v]hstack=inputs=2[v]" -map "[v]" output.mp4
# Vertical stacking
ffmpeg -i top.mp4 -i bottom.mp4 -filter_complex "[0:v][1:v]vstack=inputs=2[v]" -map "[v]" output.mp4
# 2x2 grid
ffmpeg -i input1.mp4 -i input2.mp4 -i input3.mp4 -i input4.mp4 -filter_complex "[0:v][1:v]hstack=inputs=2[top];[2:v][3:v]hstack=inputs=2[bottom];[top][bottom]vstack=inputs=2[v]" -map "[v]" output.mp4
Subtitle Integration
Soft Subtitles (Embedded, Toggleable)
# Add SRT as soft subtitle
ffmpeg -i input.mp4 -i subtitles.srt -c copy -c:s mov_text output.mp4
# Multiple subtitle tracks with language metadata
ffmpeg -i input.mp4 -i english.srt -i spanish.srt -c copy -c:s mov_text -metadata:s:s:0 language=eng -metadata:s:s:1 language=spa output.mp4
Hard Subtitles (Burned In)
# Basic subtitle burning
ffmpeg -i input.mp4 -vf "subtitles=subtitles.srt" output.mp4
# Styled subtitles
ffmpeg -i input.mp4 -vf "subtitles=subtitles.srt:force_style='Fontsize=24,Fontname=Arial,PrimaryColour=&H00FFFFFF'" output.mp4
# From embedded subtitle track
ffmpeg -i input.mkv -vf "subtitles=input.mkv:si=0" output.mp4
Watermarks and Overlays
Image Watermarks
# Basic logo overlay (top-left)
ffmpeg -i input.mp4 -i logo.png -filter_complex "overlay=10:10" output.mp4
# Bottom-right positioning
ffmpeg -i input.mp4 -i logo.png -filter_complex "overlay=main_w-overlay_w-10:main_h-overlay_h-10" output.mp4
# Center positioning
ffmpeg -i input.mp4 -i logo.png -filter_complex "overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2" output.mp4
# Semi-transparent watermark
ffmpeg -i input.mp4 -i logo.png -filter_complex "[1]format=rgba,colorchannelmixer=aa=0.5[logo];[0][logo]overlay=main_w-overlay_w-10:main_h-overlay_h-10" output.mp4
Text Watermarks
# Basic text watermark
ffmpeg -i input.mp4 -vf "drawtext=text='Copyright 2025':fontcolor=white:fontsize=24:x=10:y=10" output.mp4
# Text with background box
ffmpeg -i input.mp4 -vf "drawtext=text='My Company':fontcolor=white:fontsize=20:x=10:y=10:box=1:boxcolor=black@0.5" output.mp4
# Dynamic timestamp
ffmpeg -i input.mp4 -vf "drawtext=text='%{localtime}':fontcolor=white:fontsize=18:x=w-tw-10:y=10" output.mp4
Advanced Video Effects
Denoising
# High-quality denoising (slow)
ffmpeg -i input.mp4 -vf "nlmeans=s=1.0:p=7:r=15" output.mp4
# Fast denoising
ffmpeg -i input.mp4 -vf "hqdn3d=2:1:2:1" output.mp4
Video Stabilization
# Two-pass stabilization (best quality)
# Pass 1: Analyze
ffmpeg -i input.mp4 -vf vidstabdetect=shakiness=8:accuracy=15:result=transforms.trf -f null -
# Pass 2: Apply stabilization
ffmpeg -i input.mp4 -vf vidstabtransform=input=transforms.trf:zoom=5:smoothing=15 output.mp4
Color Correction
# Basic color adjustment
ffmpeg -i input.mp4 -vf "eq=contrast=1.2:brightness=0.1:saturation=1.3:gamma=1.1" output.mp4
# Color balance
ffmpeg -i input.mp4 -vf "colorbalance=rs=0.1:gs=-0.1:bs=0.05" output.mp4
# Automatic color correction
ffmpeg -i input.mp4 -vf "normalize" output.mp4
Streaming and Live Broadcasting
RTMP Live Streaming
Basic RTMP Stream Setup
# Stream to YouTube/Twitch from webcam
ffmpeg -f v4l2 -i /dev/video0 -f alsa -i default -c:v libx264 -preset ultrafast -tune zerolatency -b:v 2500k -c:a aac -b:a 128k -f flv rtmp://a.rtmp.youtube.com/live2/YOUR_STREAM_KEY
# Stream existing file
ffmpeg -re -i input.mp4 -c:v libx264 -c:a aac -preset ultrafast -tune zerolatency -f flv rtmp://127.0.0.1/live/stream_name
Hardware-Accelerated Streaming
# NVIDIA GPU encoding for streaming
ffmpeg -f v4l2 -i /dev/video0 -c:v h264_nvenc -preset llhq -tune ull -b:v 3000k -c:a aac -b:a 128k -f flv rtmp://ingest.server.com/live/stream_key
HLS (HTTP Live Streaming)
Basic HLS Generation
# Simple HLS conversion
ffmpeg -i input.mp4 -c:v libx264 -c:a aac -hls_time 4 -hls_playlist_type vod -hls_segment_filename "segment%d.ts" playlist.m3u8
Multi-Quality HLS (Adaptive Bitrate)
# Create multiple quality levels
ffmpeg -i input.mp4 \
-filter_complex "[0:v]split=3[v1][v2][v3]; [v1]copy[v1out]; [v2]scale=w=1280:h=720[v2out]; [v3]scale=w=640:h=360[v3out]" \
-map "[v1out]" -c:v:0 libx264 -b:v:0 5000k -maxrate:v:0 5350k -bufsize:v:0 7500k \
-map "[v2out]" -c:v:1 libx264 -b:v:1 2500k -maxrate:v:1 2675k -bufsize:v:1 3750k \
-map "[v3out]" -c:v:2 libx264 -b:v:2 1000k -maxrate:v:2 1070k -bufsize:v:2 1500k \
-map a:0 -c:a:0 aac -b:a:0 256k \
-map a:0 -c:a:1 aac -b:a:1 128k \
-map a:0 -c:a:2 aac -b:a:2 96k \
-var_stream_map "v:0,a:0 v:1,a:1 v:2,a:2" \
-master_pl_name master.m3u8 \
-f hls -hls_time 4 -hls_list_size 0 \
-hls_segment_filename "v%v/segment%d.ts" \
"v%v/playlist.m3u8"
DASH (Dynamic Adaptive Streaming)
# Basic DASH streaming
ffmpeg -i input.mp4 -c:v libx264 -c:a aac -b:v 1000k -s 1280x720 -f dash -seg_duration 4 -use_template 1 -use_timeline 1 output.mpd
# Multi-bitrate DASH
ffmpeg -i input.mp4 \
-map 0:v:0 -map 0:a:0 -map 0:v:0 -map 0:a:0 \
-b:v:0 2000k -s:v:0 1280x720 -profile:v:0 main \
-b:v:1 500k -s:v:1 640x360 -profile:v:1 baseline \
-b:a:0 128k -b:a:1 64k \
-use_timeline 1 -use_template 1 -window_size 5 \
-adaptation_sets "id=0,streams=v id=1,streams=a" \
-f dash output.mpd
Low-Latency Streaming
Ultra-Low Latency HLS
ffmpeg -i input -c:v libx264 -tune zerolatency -preset ultrafast \
-b:v 2500k -g 30 -keyint_min 30 -sc_threshold 0 \
-c:a aac -b:a 128k \
-f hls -hls_time 1 -hls_list_size 3 -hls_flags delete_segments \
-hls_allow_cache 0 playlist.m3u8
Batch Processing and Automation
Cross-Platform Batch Scripts
Windows PowerShell Batch Processing
# Audio processing batch script
$inputPath = ".\input"
$outputPath = ".\output"
if (-not (Test-Path $outputPath)) {
New-Item -ItemType Directory -Path $outputPath
}
Get-ChildItem $inputPath -Include *.mp3,*.wav,*.flac -Recurse | ForEach-Object {
$inputFile = $_.FullName
$outputFile = Join-Path $outputPath ($_.BaseName + "_processed.mp3")
Write-Host "Processing: $($_.Name)"
& ffmpeg -y -i $inputFile -af "loudnorm=I=-16:LRA=11:tp=-1.5" -c:a libmp3lame -b:a 192k $outputFile
Write-Host "Completed: $($_.Name)"
}
macOS/Linux Bash Batch Processing
#!/bin/bash
# Advanced batch processing with parallel execution
input_dir="./input"
output_dir="./output"
max_jobs=4 # Number of parallel jobs
process_file() {
local file="$1"
local filename=$(basename "$file")
local filename_no_ext="${filename%.*}"
echo "Processing: $filename"
# Complex processing chain
ffmpeg -y -i "$file" \
-af "afftdn=nr=12:nf=-25,loudnorm=I=-16:LRA=11:tp=-1.5,acompressor=threshold=0.05:ratio=3" \
-c:a libmp3lame -b:a 320k "$output_dir/${filename_no_ext}_enhanced.mp3" \
-loglevel error
echo "Completed: $filename"
}
export -f process_file
export output_dir
mkdir -p "$output_dir"
# Use GNU parallel for efficient processing
find "$input_dir" -name "*.wav" -o -name "*.flac" -o -name "*.mp3" | \
parallel -j "$max_jobs" process_file {}
Intelligent Auto-Processing
#!/bin/bash
# Quality-based intelligent processing
process_intelligent() {
local input="$1"
local output="$2"
# Detect audio properties
local bit_rate=$(ffprobe -v error -select_streams a:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1:nokey=1 "$input")
echo "Input bitrate: ${bit_rate}bps"
# Choose processing based on quality
if [[ $bit_rate -gt 256000 ]]; then
# High quality - preserve with lossless processing
ffmpeg -i "$input" -af "loudnorm=I=-16:LRA=11:tp=-1.5" -c:a flac "$output"
elif [[ $bit_rate -gt 128000 ]]; then
# Medium quality - enhance and convert to high-quality MP3
ffmpeg -i "$input" -af "dynaudnorm=p=0.9" -c:a libmp3lame -b:a 320k "$output"
else
# Low quality - apply aggressive enhancement
ffmpeg -i "$input" -af "afftdn=nr=15,dynaudnorm=p=0.95,acompressor=threshold=0.1:ratio=4" -c:a libmp3lame -b:a 256k "$output"
fi
}
Performance Optimization and Hardware Acceleration
Hardware Acceleration Setup
NVIDIA NVENC/NVDEC (2025 Best Practices)
# Basic NVENC encoding
ffmpeg -y -vsync 0 -hwaccel cuda -hwaccel_output_format cuda -i input.mp4 -c:v h264_nvenc -b:v 5M output.mp4
# High-quality NVENC with lookahead
ffmpeg -y -vsync 0 -hwaccel cuda -hwaccel_output_format cuda -i input.mp4 \
-c:v h264_nvenc -preset p6 -tune hq -b:v 5M -bufsize 5M -maxrate 10M \
-qmin 0 -g 250 -bf 3 -temporal-aq 1 -rc-lookahead 20 output.mp4
# AV1 encoding (latest GPUs)
ffmpeg -y -vsync 0 -hwaccel cuda -hwaccel_output_format cuda -i input.mp4 -c:v av1_nvenc -b:v 5M output.mp4
Intel Quick Sync Video (QSV)
# QSV encoding
ffmpeg -hwaccel qsv -c:v h264_qsv -i input.mp4 -c:v h264_qsv -b:v 5M output.mp4
# With GPU scaling
ffmpeg -hwaccel qsv -c:v h264_qsv -i input.mp4 -vf scale_qsv=1280:720 -c:v h264_qsv output.mp4
AMD Hardware Acceleration
# AMD AMF encoding
ffmpeg -i input.mp4 -c:v h264_amf -b:v 5M output.mp4
# With VAAPI support
ffmpeg -vaapi_device /dev/dri/renderD128 -i input.mp4 -vf format=nv12,hwupload -c:v h264_vaapi output.mp4
CPU Optimization
Threading Configuration
# Auto-detect optimal threads (recommended)
ffmpeg -threads 0 -i input.mp4 output.mp4
# Manual thread control
ffmpeg -threads 8 -i input.mp4 -c:v libx264 -preset medium output.mp4
# Thread type control
ffmpeg -i input.mp4 -c:v libx264 -threads 8 -thread_type frame+slice output.mp4
Memory Optimization
# Minimize memory footprint
ffmpeg -i input.mp4 -c:v libx264 -bufsize 512k -maxrate 1M -threads 2 output.mp4
# Control buffer sizes
ffmpeg -thread_queue_size 512 -i input.mp4 -c copy output.mp4
Quality vs Speed Optimization
Preset Selection (H.264/H.265)
# Speed-optimized (fastest)
ffmpeg -i input.mp4 -c:v libx264 -preset ultrafast -crf 23 output.mp4
# Quality-optimized (slowest, best compression)
ffmpeg -i input.mp4 -c:v libx264 -preset slow -crf 18 output.mp4
# Balanced approach
ffmpeg -i input.mp4 -c:v libx264 -preset medium -crf 21 output.mp4
Two-Pass Encoding (Maximum Quality)
# Two-pass H.264 for precise bitrate control
ffmpeg -y -i input.mp4 -c:v libx264 -b:v 2M -pass 1 -an -f null /dev/null
ffmpeg -i input.mp4 -c:v libx264 -b:v 2M -pass 2 -c:a aac -b:a 128k output.mp4
# Two-pass H.265
ffmpeg -y -i input.mp4 -c:v libx265 -b:v 1.5M -x265-params pass=1 -an -f null /dev/null
ffmpeg -i input.mp4 -c:v libx265 -b:v 1.5M -x265-params pass=2 -c:a aac output.mp4
Troubleshooting Common Issues
Installation and Setup Issues
Windows: "ffmpeg is not recognized"
Solutions:
# Check PATH
where ffmpeg
# Manually add to current session
set PATH=%PATH%;C:\ffmpeg\bin
# Verify installation
ffmpeg -version
macOS: Permission denied
# Fix permissions
sudo chown -R $(whoami) $(brew --prefix)
brew doctor
brew reinstall ffmpeg
Linux: Codec not found
# Check available codecs
ffmpeg -codecs | grep h264
# Install additional codecs (Ubuntu)
sudo apt install ubuntu-restricted-extras
sudo apt install ffmpeg-full
# Compile with additional codecs
sudo apt install libx264-dev libx265-dev libvpx-dev
Performance Issues
Slow Encoding
Diagnostics:
# Monitor CPU usage
top -p $(pgrep ffmpeg)
# Check GPU utilization (NVIDIA)
nvidia-smi dmon -s u
# Enable detailed logging
ffmpeg -loglevel debug -i input.mp4 output.mp4
Solutions:
# Use hardware acceleration
ffmpeg -hwaccel cuda -i input.mp4 -c:v h264_nvenc output.mp4
# Optimize threading
ffmpeg -threads 0 -i input.mp4 -preset fast output.mp4
# Reduce quality temporarily
ffmpeg -i input.mp4 -crf 28 -preset ultrafast output.mp4
Memory Issues
# Reduce memory usage
ffmpeg -i large_file.mp4 -threads 2 -bufsize 1M -maxrate 5M output.mp4
# Process in chunks
ffmpeg -ss 0 -t 300 -i input.mp4 part1.mp4
ffmpeg -ss 300 -t 300 -i input.mp4 part2.mp4
Audio/Video Sync Issues
Fix Sync Problems
# Fix negative timestamps
ffmpeg -i input.mp4 -c:v copy -c:a copy -avoid_negative_ts make_zero output.mp4
# Manually adjust audio delay (3.5 seconds)
ffmpeg -i input.mp4 -itsoffset 3.5 -i input.mp4 -map 0:v -map 1:a -c copy output.mp4
# Re-sync with PTS adjustment
ffmpeg -i input.mp4 -c:v copy -c:a copy -fflags +genpts output.mp4
Codec and Container Issues
Unsupported Format
# Check file information
ffprobe -i problematic_file.mp4
# Convert to compatible format
ffmpeg -i input.mkv -c:v libx264 -profile:v main -level:v 4.0 -c:a aac output.mp4
# Force container change
ffmpeg -i input.mov -c copy -f mp4 output.mp4
Corrupted File Recovery
# Attempt to fix corrupted file
ffmpeg -err_detect ignore_err -i corrupted.mp4 -c copy fixed.mp4
# Re-encode problematic stream
ffmpeg -i corrupted.mp4 -c:v libx264 -c:a copy recovered.mp4
Network and Streaming Issues
Streaming Connection Problems
# Test RTMP connection
ffmpeg -f lavfi -i testsrc2=duration=10:size=640x480:rate=30 -f flv rtmp://test.server/live/test
# Increase timeout values
ffmpeg -rtmp_live_timeout 30000 -i rtmp://source -c copy output.mp4
# Add reconnection attempts
ffmpeg -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 2 -i rtmp://source output.mp4
Complete Command Reference
Essential Global Options
# File Operations
-y # Overwrite output files
-n # Never overwrite output files
-hide_banner # Suppress printing banner
-v quiet|error|warning|info|verbose|debug # Logging level
# Performance
-threads N # Number of threads (0 = auto)
-thread_queue_size N # Maximum packets in queue
-filter_threads N # Number of threads for filtering
Input/Output Options
# Input
-i filename # Input file
-ss time # Start time offset
-t duration # Duration limit
-to time # Stop time
-itsoffset offset # Input timestamp offset
# Output
-c codec # Set codec (copy, libx264, etc.)
-c:v codec # Video codec
-c:a codec # Audio codec
-f format # Force format
Video Options
# Quality and Encoding
-crf N # Constant Rate Factor (0-51)
-b:v bitrate # Video bitrate (1M, 500k)
-maxrate bitrate # Maximum bitrate
-bufsize size # Rate control buffer size
-preset preset # Encoding speed preset
-profile:v profile # Encoding profile
# Resolution and Frame Rate
-s WxH # Frame size
-vf filter # Video filter
-r fps # Frame rate
-g GOP # GOP size (keyframe interval)
# Advanced
-pix_fmt format # Pixel format (yuv420p, etc.)
-aspect ratio # Display aspect ratio
-vsync method # Video sync method
Audio Options
# Quality and Encoding
-b:a bitrate # Audio bitrate (128k, 320k)
-ar samplerate # Sample rate (44100, 48000)
-ac channels # Channel count (1=mono, 2=stereo)
-af filter # Audio filter
# Advanced
-acodec codec # Audio codec (deprecated, use -c:a)
-vol volume # Volume (deprecated, use -af volume)
Stream Mapping
# Basic Mapping
-map input:stream # Map specific stream
-map 0:v # All video streams from input 0
-map 0:a:0 # First audio stream from input 0
# Advanced Mapping
-map_metadata input # Copy metadata
-map_chapters input # Copy chapters
-disposition:s:0 default # Set subtitle disposition
Filter Options
# Video Filters
-vf "filter1,filter2" # Simple filter chain
-filter_complex "complex_filter" # Complex filter graph
# Common Video Filters
scale=W:H # Scale video
crop=W:H:X:Y # Crop video
transpose=1 # Rotate 90° clockwise
hflip # Horizontal flip
vflip # Vertical flip
fps=N # Change frame rate
Hardware Acceleration
# General
-hwaccel method # auto, cuda, qsv, vaapi
-hwaccel_device N # Hardware device index
# NVIDIA
-c:v h264_nvenc # NVENC H.264 encoder
-c:v h264_cuvid # CUVID H.264 decoder
-preset p1-p7 # NVENC preset (p1=fastest, p7=slowest)
# Intel QSV
-c:v h264_qsv # QSV H.264 encoder
-look_ahead 1 # Enable lookahead
# AMD
-c:v h264_amf # AMF H.264 encoder
Real-World Use Cases and Projects
Content Creation Workflows
Podcast Production Pipeline
#!/bin/bash
# Complete podcast processing workflow
# 1. Noise reduction and normalization
ffmpeg -i raw_podcast.wav \
-af "highpass=f=80,lowpass=f=15000,afftdn=nr=10,loudnorm=I=-16:LRA=11:tp=-1.5" \
clean_podcast.wav
# 2. Chapter marking (if chapters.txt exists)
if [[ -f chapters.txt ]]; then
ffmpeg -i clean_podcast.wav -i chapters.txt -map_metadata 1 -c copy podcast_with_chapters.mp3
fi
# 3. Multiple format export
ffmpeg -i clean_podcast.wav \
-c:a libmp3lame -b:a 128k podcast_web.mp3 \
-c:a libopus -b:a 64k podcast_mobile.opus \
-c:a aac -b:a 128k podcast_iTunes.m4a
YouTube Video Processing
#!/bin/bash
# YouTube-optimized video processing
input="$1"
title="$2"
# Main upload version (1080p, optimized)
ffmpeg -i "$input" \
-c:v libx264 -profile:v high -level:v 4.2 -crf 21 -preset slower \
-s 1920x1080 -r 30 -g 60 \
-c:a aac -b:a 192k -ar 48000 \
-movflags +faststart \
-metadata title="$title" \
youtube_main.mp4
# Thumbnail extraction (middle frame)
duration=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$input")
middle_time=$(echo "$duration / 2" | bc -l)
ffmpeg -ss $middle_time -i "$input" -vframes 1 -q:v 2 -s 1280x720 thumbnail.jpg
# Preview clips for social media (15-second clips)
ffmpeg -i "$input" -ss 30 -t 15 -c:v libx264 -crf 23 -s 720x720 -c:a aac -b:a 128k instagram_preview.mp4
Live Streaming Production
Multi-Camera Live Stream Setup
#!/bin/bash
# Professional multi-camera streaming setup
# Camera inputs (adjust device paths as needed)
CAM1="/dev/video0"
CAM2="/dev/video2"
AUDIO_DEVICE="default"
STREAM_KEY="your_stream_key"
RTMP_URL="rtmp://a.rtmp.youtube.com/live2"
# Multi-camera with picture-in-picture
ffmpeg \
-f v4l2 -i $CAM1 -f v4l2 -i $CAM2 -f alsa -i $AUDIO_DEVICE \
-filter_complex "
[0:v]scale=1920:1080[main];
[1:v]scale=480:270[pip];
[main][pip]overlay=1420:790[output]
" \
-map "[output]" -map 2:a \
-c:v libx264 -preset fast -tune zerolatency \
-b:v 4000k -maxrate 4000k -bufsize 8000k -g 60 \
-c:a aac -b:a 128k -ar 48000 \
-f flv $RTMP_URL/$STREAM_KEY
Automated Stream Monitoring
#!/bin/bash
# Stream health monitoring script
RTMP_URL="rtmp://your-server/live/stream"
LOG_FILE="/var/log/stream_monitor.log"
monitor_stream() {
while true; do
# Check stream health
if ! ffprobe -v quiet -show_streams "$RTMP_URL" 2>/dev/null; then
echo "$(date): Stream offline, attempting restart" >> $LOG_FILE
# Restart stream from backup source
ffmpeg -re -i /path/to/backup/playlist.m3u8 \
-c copy -f flv "$RTMP_URL" &
STREAM_PID=$!
echo "$(date): Backup stream started (PID: $STREAM_PID)" >> $LOG_FILE
fi
sleep 30
done
}
monitor_stream
Enterprise Media Processing
Automated Transcoding Service
#!/bin/bash
# Enterprise transcoding service with multiple outputs
input_dir="/media/input"
output_dir="/media/output"
archive_dir="/media/archive"
process_video() {
local input="$1"
local basename=$(basename "$input" | sed 's/\.[^.]*$//')
local output_path="$output_dir/$basename"
mkdir -p "$output_path"
# Multiple quality encodes in parallel
(
# 4K version
ffmpeg -i "$input" -c:v libx264 -crf 18 -preset slower -s 3840x2160 \
-c:a aac -b:a 256k -movflags +faststart "$output_path/${basename}_4k.mp4"
) &
(
# 1080p version
ffmpeg -i "$input" -c:v libx264 -crf 21 -preset medium -s 1920x1080 \
-c:a aac -b:a 192k -movflags +faststart "$output_path/${basename}_1080p.mp4"
) &
(
# 720p version
ffmpeg -i "$input" -c:v libx264 -crf 23 -preset fast -s 1280x720 \
-c:a aac -b:a 128k -movflags +faststart "$output_path/${basename}_720p.mp4"
) &
# Wait for all encodes to complete
wait
# Generate HLS playlist
ffmpeg -i "$output_path/${basename}_1080p.mp4" \
-c copy -f hls -hls_time 4 -hls_playlist_type vod \
"$output_path/${basename}.m3u8"
# Move original to archive
mv "$input" "$archive_dir/"
echo "Processing complete: $basename"
}
# Monitor input directory
inotifywait -m "$input_dir" -e create -e moved_to --format '%w%f' |
while read file; do
if [[ "$file" == *.mp4 ]] || [[ "$file" == *.mov ]] || [[ "$file" == *.avi ]]; then
echo "New file detected: $file"
process_video "$file"
fi
done
Quality Assurance and Analysis
Video Quality Analysis Suite
#!/bin/bash
# Comprehensive video quality analysis
analyze_video() {
local input="$1"
local output_report="${input%.*}_analysis.txt"
echo "=== Video Analysis Report ===" > "$output_report"
echo "File: $input" >> "$output_report"
echo "Date: $(date)" >> "$output_report"
echo "" >> "$output_report"
# Basic file information
echo "=== File Information ===" >> "$output_report"
ffprobe -v quiet -print_format json -show_format -show_streams "$input" >> "$output_report"
echo "" >> "$output_report"
# Audio levels analysis
echo "=== Audio Analysis ===" >> "$output_report"
ffmpeg -i "$input" -af "volumedetect,astats" -f null - 2>&1 | \
grep -E "(mean_volume|max_volume|RMS|Peak)" >> "$output_report"
echo "" >> "$output_report"
# Scene detection
echo "=== Scene Changes ===" >> "$output_report"
ffprobe -f lavfi -i "movie=$input,select=gt(scene\,0.3)" -show_entries frame=pkt_pts_time -v quiet -of csv=p=0 | \
head -20 >> "$output_report"
echo "" >> "$output_report"
# Generate thumbnail grid
local thumbnail_grid="${input%.*}_thumbnails.jpg"
ffmpeg -i "$input" -vf "thumbnail,scale=320:240,tile=4x3" -frames:v 1 "$thumbnail_grid"
echo "Analysis complete. Report: $output_report"
echo "Thumbnail grid: $thumbnail_grid"
}
# Usage: ./analyze_video.sh video.mp4
analyze_video "$1"
This comprehensive FFmpeg tutorial and reference manual provides everything needed to master FFmpeg from basic installation through advanced professional workflows. Each section includes practical, cross-platform examples that work on Windows, macOS, and Linux, with current best practices for 2025 and beyond.