4.1 滤镜图:加工流水线的拓扑


4.1 滤镜图:加工流水线的拓扑

本节摘要:FFmpeg 的滤镜不是一条命令,而是一张图。本节讲清滤镜图的组成元素(节点、垫、连线)、简单链与复杂图的区分,以及 -vf 与 -filter_complex 两种写法的边界,帮你建立「滤镜 = 管线里的子流水线」的认知。

本节目标:阅读完本节,你应当能够:

  1. 画出滤镜图的基本元素:滤镜节点、输入垫、输出垫、连接线
  2. 判断一个任务该用 -vf 简单链还是 -filter_complex 复杂图
  3. 读懂复杂图语法(分号、方括号、命名流),把多路流接进图里

一、一个反例开场

不少人写滤镜是「一个滤镜一串参数」的线性思维,于是遇到要「把两段视频叠在一起,一段做背景一段做画中画」就卡住了——单条链根本画不出来。问题不在滤镜本身,而在你把滤镜理解成了「命令」,而它其实是「图」。

FFmpeg 的设计里,滤镜是节点,节点有输入垫(pad)和输出垫,垫之间用线连接,数据从上游流向下游。多个节点连成链,多条链交汇成图。命令行里 -vf 写的是最简单的一串链,-filter_complex 则能描述任意拓扑——分叉、汇合、多输入多输出都行。

二、核心原理:滤镜图的解剖

三个基本元素

  • 滤镜节点:一个具体的处理单元,比如 scalecropoverlayamix
  • 输入垫 / 输出垫:节点接收数据与吐出数据的接口,用 [in][out][v0] 这类名字标识
  • 连接线:把 A 的输出垫接到 B 的输入垫,数据就从 A 流向 B

简单链:-vf 的写法

# 缩放后裁剪:一串从左到右的节点 ffmpeg -i input.mp4 -vf "scale=1280:720,crop=640:360:320:180" output.mp4

这条命令里,scalecrop 用逗号连成一条链,数据先缩放再裁剪。链 = 逗号连接的节点序列,这是最简单的情况。

复杂图:-filter_complex 的写法

当需要多路输入、或中间有分叉汇合,链不够用,得上图。语法三件套:

  • 逗号 ,:链内节点连接
  • 分号 ;:链与链之间的分隔(并列的多条链)
  • 方括号 [标签]:给流起名字,让多条链之间互相引用
# 背景视频 + 右上角画中画:两个输入,两条链,最后 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 能看单个滤镜的输入输出说明——善用这两个帮助命令,滤镜图的谜团就解掉一大半。

本节要点回顾

  • 图而非命令:滤镜是节点、垫、连线的图,-vf 只是最简单的一种拓扑
  • 语法三件套:逗号连链、分号分链、方括号命名流
  • 判断标准:有汇合/分叉/多输入 → -filter_complex;单链直通 → -vf
  • -map 必配:用复杂图后必须显式 -map 输出流,否则可能空输出
  • 先预览后定稿:滤镜调试走 ffplay 预览闭环,确认效果再进 ffmpeg

下一节看视频滤镜的四大主力——缩放、裁剪、水印、变速,把图落到具体命令。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U