本节摘要:FFmpeg 的滤镜不是一条命令,而是一张图。本节讲清滤镜图的组成元素(节点、垫、连线)、简单链与复杂图的区分,以及 -vf 与 -filter_complex 两种写法的边界,帮你建立「滤镜 = 管线里的子流水线」的认知。
本节目标:阅读完本节,你应当能够:
不少人写滤镜是「一个滤镜一串参数」的线性思维,于是遇到要「把两段视频叠在一起,一段做背景一段做画中画」就卡住了——单条链根本画不出来。问题不在滤镜本身,而在你把滤镜理解成了「命令」,而它其实是「图」。
FFmpeg 的设计里,滤镜是节点,节点有输入垫(pad)和输出垫,垫之间用线连接,数据从上游流向下游。多个节点连成链,多条链交汇成图。命令行里 -vf 写的是最简单的一串链,-filter_complex 则能描述任意拓扑——分叉、汇合、多输入多输出都行。
scale、crop、overlay、amix[in]、[out]、[v0] 这类名字标识# 缩放后裁剪:一串从左到右的节点 ffmpeg -i input.mp4 -vf "scale=1280:720,crop=640:360:320:180" output.mp4
这条命令里,scale 与 crop 用逗号连成一条链,数据先缩放再裁剪。链 = 逗号连接的节点序列,这是最简单的情况。
当需要多路输入、或中间有分叉汇合,链不够用,得上图。语法三件套:
,:链内节点连接;:链与链之间的分隔(并列的多条链)[标签]:给流起名字,让多条链之间互相引用# 背景视频 + 右上角画中画:两个输入,两条链,最后 overlay 汇合 ffmpeg -i bg.mp4 -i pip.mp4 \ -filter_complex "[0:v]scale=1280:720[bga];[1:v]scale=320:180[pips];[bga][pips]overlay=x=W-w-20:y=20[out]" \ -map "[out]" -c:v libx264 combined.mp4
逐段解读:
[0:v]scale=1280:720[bga]:取输入 0 的视频流,缩放,存成名为 bga 的流[1:v]scale=320:180[pips]:取输入 1 的视频流,缩放成小窗,存成 pips[bga][pips]overlay=x=W-w-20:y=20[out]:把 pips 叠到 bga 上,位置在右上角(W 是背景宽,w 是小窗宽),结果叫 out-map "[out]":输出只要合成后的流这就是「图」的威力:两条独立链各自加工,最后汇合到一个节点。
下面这张图画出了简单链与复杂图的对比。

左侧是线性思维,右侧是图思维。线性链用逗号串起来;只要出现「两条链的数据要合到一起」或「一个输入分出多路」,就必须用分号和方括号搭图。判断标准就一句话:有没有多路流的汇合或分叉。
什么时候用 -vf,什么时候用 -filter_complex?
| 场景 | 写法 | 原因 |
|---|---|---|
| 单输入单输出,一串滤镜 | -vf "a,b,c" |
无分叉汇合,链够用 |
| 多输入合并(画中画、混音) | -filter_complex |
需要命名流并引用多路 |
| 中间流要复用(同一帧同时做两种效果) | -filter_complex |
需要分叉 |
| 输入输出流数量不对等 | -filter_complex |
-vf 只能一一对应 |
排查滤镜问题的顺序:先用 ffplay -vf 预览确认效果对(第 3 章),再进 ffmpeg;报错多在「标签没对上」——写了 [out] 但 -map 也写 [out],两边必须一致。
常见坑:
-filter_complex与-vf同时用会冲突,复杂的图里所有滤镜都写进-filter_complex。另外,用了复杂图后,输出流要显式用-map指定,FFmpeg 不会再「自动选」,漏掉-map会得到空输出或报错。
💡 关键直觉:把滤镜图当「数据流拓扑」而不是「命令序列」。任何多流场景,先画图(哪几个输入、在哪汇合),再写语法,几乎不会错。
滤镜图相关的报错很有特点,多半能直接翻译成图的问题。Filter ... has an unconnected output 说明某个输出垫没接上——你在语法里写了一条链,但它的输出没有归宿;Cannot find a matching stream 通常是你引用了不存在的流标签。
# 典型的标签引用错误:没定义 [bg] 就引用 [bg] ffmpeg -i a.mp4 -i b.mp4 -filter_complex "[bga][b]overlay" out.mp4
这类错误最好的排查方式不是盯着语法看,而是把命令拆成几行,先确认每条链都能独立工作,再确认标签一一对应。工具 ffmpeg -filters 能列出所有可用滤镜,ffmpeg -h filter=overlay 能看单个滤镜的输入输出说明——善用这两个帮助命令,滤镜图的谜团就解掉一大半。
下一节看视频滤镜的四大主力——缩放、裁剪、水印、变速,把图落到具体命令。