Simple FFmpeg commands use -vf (a single linear chain). The moment you need multiple inputs or branching — a watermark, picture-in-picture, a split-and-recombine color grade — you graduate to filter_complex. It describes a directed graph of filters connected by named labels like [base] and [v].
Key takeaways
filter_complexconnects filters with named pads:[in]filter[out].overlaycomposites one stream over another — watermarks, PiP, logos.scale,pad, andcropreshape the frame;setsar=1avoids stretch.- Color tools:
eq,curves,colorchannelmixer,colorbalance. - Chain filters with
,and separate branches with;.
Reading a filter graph
Two rules unlock the whole syntax. A comma chains filters on the same stream; a semicolon ends one branch and starts another. Labels in square brackets name the inputs and outputs so branches can reconnect:
[0:v]scale=1920:-2,setsar=1[base]; [1:v]format=rgba, colorchannelmixer=aa=0.6[ov]; [base][ov]overlay=(W-w)/2:(H-h)/2[v]
That graph scales the main clip to 1080p, makes the second input 60% opaque, and centers it as an overlay — a watermark or logo in three lines.
Overlay: watermarks and picture-in-picture
The overlay filter takes a base and an overlay stream and positions the second using x:y. The variables W/H (base size) and w/h (overlay size) make alignment easy:
- Top-left logo:
overlay=20:20 - Bottom-right:
overlay=W-w-20:H-h-20 - Centered:
overlay=(W-w)/2:(H-h)/2
For picture-in-picture, scale the overlay down first: [1:v]scale=480:-1[pip];[0:v][pip]overlay=W-w-30:30.
Scale, pad, and crop
Resizing is the most common operation, and the most common source of squashed video. Always pair scale with setsar=1, and use -2 to keep dimensions even:
# fit 16:9 into a 1:1 square with padding [0:v]scale=1080:-2,setsar=1, pad=1080:1080:0:(oh-ih)/2:black[v] # crop a 1080x1080 center square [0:v]crop=ih:ih:(iw-ih)/2:0[v]
Color correction and grading
FFmpeg ships a deep color toolkit. eq handles quick brightness/contrast/saturation; curves gives you per-channel control; colorchannelmixer and colorbalance let you push tones precisely:
[0:v]eq=contrast=1.1:saturation=1.15:brightness=0.02, curves=preset=lighter, colorbalance=rs=0.05:bs=-0.05[v]
Chroma key (green screen)
Composite a subject over a new background with chromakey, then overlay the result:
[1:v]chromakey=0x00FF00:0.30:0.10[key]; [0:v][key]overlay[v]
Chaining it all into one render
Real edits combine these. Here a clip is scaled, color-graded, watermarked, and handed off — a single reproducible command you can version-control:
ffmpeg -i main.mp4 -i logo.png -filter_complex "
[0:v]scale=1920:-2,setsar=1,
eq=contrast=1.08:saturation=1.1[base];
[1:v]format=rgba,colorchannelmixer=aa=0.5[ov];
[base][ov]overlay=W-w-30:H-h-30[v]
" -map "[v]" -map 0:a -c:a copy out.mp4From filter graphs to a real timeline
FFmpegLab is built around exactly this idea: a visual timeline on top, the live filter_complex graph underneath. Build effects with controls, then open the generated script and tweak the graph by hand — every effect is a real, forkable FFmpeg filter chain. Combine it with xfade transitions and amix audio, all running privately and offline in the browser.