What You Will Learn

  • The concept of a filtergraph
  • When to use a simple filter (-vf) versus a complex filter (-filter_complex)
  • How to write filter chains (the difference between , and ;)
  • How to use labels ([label])
  • Practical examples of multi-input and multi-output filters

Tested with: FFmpeg 6.1
Target OS: Windows / macOS / Linux


What Is a Filtergraph

An FFmpeg filtergraph is a directed graph of connected filter nodes. Video and audio frames flow between the nodes, and each node performs a transformation on them.

input → [scale] → [overlay] → output

                  [logo input]

A simple single-input, single-output filter is specified with -vf (video) or -af (audio). When you need multiple inputs, multiple outputs, or parallel chains, you use -filter_complex.


Simple Filters: -vf and -af

Video Filters (-vf)

ffmpeg -i input.mp4 -vf "scale=1280:720" output.mp4
ffmpeg -i input.mp4 -vf "scale=1280:720,fps=30" output.mp4

Connecting multiple filters with , creates a filter chain.

Audio Filters (-af)

ffmpeg -i input.mp4 -af "volume=2.0" output.mp4

Filter Chain Separators

SymbolMeaning
,Move to the next filter within the same chain (the output of the previous filter becomes the input of the next)
;Start a separate filter chain (a parallel chain)

Basics of -filter_complex

In -filter_complex, you identify streams using labels ([name]).

Scale and Bind to a Specific Output Label

ffmpeg -i input.mp4 -filter_complex "[0:v]scale=640:360[v]" -map "[v]" -map 0:a output.mp4
  • [0:v] — the video stream of input 0
  • scale=640:360 — the filter
  • [v] — the output label (any name you choose)
  • -map "[v]" — map the labeled output to the output file

Chaining Multiple Filters

ffmpeg -i input.mp4 -filter_complex "[0:v]scale=1280:720,fps=30[v]" -map "[v]" -map 0:a -c:a copy output.mp4

Watermark (Image Overlay)

An example of the overlay filter, which takes two inputs:

ffmpeg -i input.mp4 -i logo.png \
  -filter_complex "[0:v][1:v]overlay=10:10[v]" \
  -map "[v]" -map 0:a -c:a copy output.mp4
  • [0:v] — the background video
  • [1:v] — the logo image
  • overlay=10:10 — overlay it at position (10,10) from the top-left corner

Creating Multiple Outputs (Generate a Thumbnail and the Main Video at Once)

ffmpeg -i input.mp4 \
  -filter_complex "[0:v]scale=1280:720[main];[0:v]scale=320:180[thumb]" \
  -map "[main]" -c:v libx264 -crf 23 main.mp4 \
  -map "[thumb]" -c:v libx264 -crf 28 thumb.mp4

This generates two output files from a single input at the same time.


Processing Audio and Video Simultaneously

An example that scales the video and adjusts the audio volume at the same time:

ffmpeg -i input.mp4 \
  -filter_complex "[0:v]scale=1280:720[v];[0:a]volume=1.5[a]" \
  -map "[v]" -map "[a]" -c:v libx264 -crf 23 output.mp4

Mixing Multiple Audio Streams with amix

Mix background music with the main audio:

ffmpeg -i main.mp4 -i bgm.mp3 \
  -filter_complex "[0:a][1:a]amix=inputs=2:duration=first:dropout_transition=2[a]" \
  -map 0:v -map "[a]" -c:v copy output.mp4

Splitting a Stream with split

Split a single video stream into two and process each separately:

ffmpeg -i input.mp4 \
  -filter_complex "[0:v]split[v1][v2];[v1]scale=1280:720[main];[v2]scale=320:180[preview]" \
  -map "[main]" -c:v libx264 -crf 23 main.mp4 \
  -map "[preview]" -c:v libx264 -crf 30 preview.mp4

Common Errors and How to Fix Them

Filtergraph 'xxx' was defined for video output stream 0:0 but additional output stream xxx of same type was not specified

When using -filter_complex, you must always specify the output label with -map "[label]". Mixing -vf and -filter_complex causes conflicts.

Invalid option -vf when using filter_complex

You cannot use -vf and -af while using -filter_complex. Consolidate all of your filter processing into -filter_complex.


Measured Example

If you need to create a 720p main output and a 360p preview from the same 1080p/30fps, 2-minute input, split lets FFmpeg decode the input only once:

ffmpeg -i input.mp4 \
  -filter_complex "[0:v]split=2[v1][v2];[v1]scale=1280:720[main];[v2]scale=640:360[preview]" \
  -map "[main]" -c:v libx264 -crf 23 main.mp4 \
  -map "[preview]" -c:v libx264 -crf 28 preview.mp4

This avoids doing the input read and decode twice, but it still encodes two outputs. On a typical 8-core desktop, it may take about 1.3–1.8x as long as producing only the 720p output. Results vary by environment.


Common Pitfalls

  • Symptom: filters do not connect because , and ; are confused. Cause: , is a serial link inside one chain, while ; separates independent chains. Fix: use , to process a single stream step by step, and ; when you branch or merge with labels. For example, scale=...,fps=... is serial, and [0:v]...[v];[0:a]...[a] is parallel.

  • Symptom: an Output with label 'x' does not exist error. Cause: an output label defined in -filter_complex was never -mapped, or the name does not match. Fix: always reference the final label (e.g. [v]) with -map "[v]". Label names must match exactly, including case.

  • Symptom: reusing the same input label twice errors out. Cause: each label can be consumed only once. Fix: when you need the same stream more than once, duplicate it with split (video) or asplit (audio) into separate labels. See the split example above.

  • Symptom: an error from mixing -filter_complex and -vf. Cause: the two are mutually exclusive and cannot be combined. Fix: consolidate all filtering into -filter_complex.


FAQ

Q. When should I use -vf versus -filter_complex? A. A simple single-input, single-output operation is fine with -vf (or -af for audio). Use -filter_complex when you need multiple inputs (overlay, mix), multiple outputs, or branching and merging.

Q. Are there rules for label names? A. You can use any alphanumeric name such as [v] or [main]. For readability, prefer descriptive names like [thumb]. Reference inputs as [0:v] or [1:a], in the form “input index : type.”

Q. Can I produce multiple outputs from one decode? A. Yes. Duplicate the stream with split and send each copy to a different file with its own -map. The input is decoded once, avoiding a duplicate read.

Q. Can I process audio and video at the same time? A. Yes. Process them in separate chains, e.g. [0:v]...[v];[0:a]...[a], and map both with -map "[v]" -map "[a]".

Q. Does filter order affect the result? A. It does. For example, placing crop before or after scale changes the outcome. A serial chain is applied left to right, so arrange the filters in the order you intend.



Primary sources: ffmpeg.org/ffmpeg-filters.html / trac.ffmpeg.org/wiki/FilteringGuide