C.W.K.
Stream
Lesson 10 of 10 · published

Complex Filter Graphs

~12 min · filter_complex, split, concat, advanced

Level 0Viewer
0 XP0/73 lessons0/15 achievements
0/100 XP to next level100 XP to go0% complete

When chains aren't enough

Real-world tasks need branching, splitting, and re-merging streams. Three patterns cover most:

  • split — duplicate one stream into N. [0:v]split=2[a][b].
  • concat filter — join inputs back together (re-encode required).
  • hstack/vstack — stack videos side by side or top-bottom for comparisons.

Code

Side-by-side comparison (split + scale + hstack)·bash
# Show original next to graded version, same height
ffmpeg -i in.mp4 \
  -filter_complex "[0:v]split=2[orig][graded]; \
                   [graded]eq=contrast=1.2:saturation=1.3[graded2]; \
                   [orig]scale=960:-2[origs]; \
                   [graded2]scale=960:-2[gradeds]; \
                   [origs][gradeds]hstack[outv]" \
  -map "[outv]" -map 0:a \
  -c:v libx264 -crf 20 -preset slow \
  -c:a copy \
  comparison.mp4
Picture-in-picture with logo + lower-third all at once·bash
ffmpeg -i screen.mp4 -i webcam.mp4 -i logo.png \
  -filter_complex "[1:v]scale=320:-2[cam]; \
                   [2:v]scale=140:-2[lg]; \
                   [0:v][cam]overlay=W-w-20:H-h-20[withcam]; \
                   [withcam][lg]overlay=20:20[withlogo]; \
                   [withlogo]drawtext=fontfile=/System/Library/Fonts/Supplemental/Arial.ttf:text='LIVE':fontcolor=red:fontsize=48:x=20:y=H-th-20:box=1:boxcolor=white@0.7:boxborderw=10[outv]" \
  -map "[outv]" -map 0:a \
  -c:v libx264 -crf 20 -preset slow \
  -c:a aac -b:a 192k \
  full_overlay.mp4
Concat heterogeneous clips·bash
# Three different sources, normalize then concat
ffmpeg -i a.mov -i b.webm -i c.mkv \
  -filter_complex "[0:v]scale=1920:1080,fps=30,setsar=1[v0]; \
                   [1:v]scale=1920:1080,fps=30,setsar=1[v1]; \
                   [2:v]scale=1920:1080,fps=30,setsar=1[v2]; \
                   [v0][0:a][v1][1:a][v2][2:a]concat=n=3:v=1:a=1[outv][outa]" \
  -map "[outv]" -map "[outa]" \
  -c:v libx264 -crf 20 -preset slow \
  -c:a aac -b:a 192k \
  joined.mp4

External links

Exercise

Build the side-by-side comparison filtergraph and run it on one of your own clips. Verify the orig and graded sides differ. Then build the full PiP-with-logo-and-lower-third recipe — replace the 'LIVE' badge with your own brand name. Measure: did the encode complete in reasonable time?

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.