滤镜链基础语法
本教程共 32 篇 · 第 23 篇 · 更新于 2026-08-09 · 约 5 分钟阅读
本节目标:彻底搞懂 FFmpeg 滤镜的语法规则。看完这章,任何
-vf、-af、-filter_complex命令你都能读懂、能自己拼。
FFmpeg 的滤镜(filter)是处理音视频画面的核心。缩放、裁剪、加水印、调速、混音,全靠滤镜。但很多人看到 -filter_complex "[0:v][1:v]overlay=...[v]" 就头大,其实它的语法只有三层,搞懂就不慌。
一、三层结构
从简到繁,三个概念:
- filter(滤镜):一个最小操作单元,比如
scale=1280:720、crop=640:480、volume=2.0。 - filterchain(滤镜链):一串用逗号
,连接的滤镜,前一个的输出是后一个的输入。 - filtergraph(滤镜图):多条滤镜链用分号
;隔开,可以有分支、汇合、多输入多输出。
filter1,filter2,filter3 ← 一条 filterchain
filterchain1;filterchain2;filterchain3 ← 一个 filtergraph
二、简单滤镜:-vf 和 -af
只处理一个视频流或一个音频流时,用 -vf(video filter)或 -af(audio filter):
ffmpeg -i input.mp4 -vf "scale=1280:720,fps=30" output.mp4
这条命令做了两件事:先缩放,再改帧率。逗号表示串联,数据从左往右流。
input → scale → fps → output
音频同理:
ffmpeg -i input.mp4 -af "volume=2.0,atempo=1.5" output.mp4
先加大音量,再变速。
选项里有冒号和逗号怎么办
滤镜的参数用冒号 : 分隔,比如 scale=宽:高。如果参数值里本身有特殊字符(空格、冒号、逗号),要用引号或转义:
ffmpeg -i input.mp4 -vf "drawtext=text='Hello World':fontsize=24:x=10:y=10" output.mp4
整个 -vf 的值用双引号包住,内部文字用单引号,这是最常见的写法。
三、缓冲标签:[name]
当滤镜图需要分支或合流时,用方括号标签给中间结果命名:
[输入标签]滤镜链[输出标签]
标签可以随便起,比如 [v0]、[scaled]、[a_mix]。输入标签从输入文件取流([0:v] 表示第一个输入的视频流),输出标签要么喂给下一条链,要么在命令末尾用 -map 引用。
举个最简单的例子——把视频缩小后再加水印:
ffmpeg -i input.mp4 -i logo.png -filter_complex \
"[0:v]scale=1280:720[bg];[bg][1:v]overlay=10:10[v]" \
-map "[v]" output.mp4
拆解:
[0:v]scale=1280:720[bg]:取第 0 个输入的视频流,缩放后命名为[bg]。[bg][1:v]overlay=10:10[v]:把[bg]作为底图,第 1 个输入(logo)叠在 (10,10),结果命名为[v]。- 两条链用分号
;隔开。 -map "[v]"把最终结果输出。
[0:v] → scale → [bg] ──┐
├→ overlay → [v] → output
[1:v] ──────────────────┘
四、为什么需要 -filter_complex
-vf 和 -af 只能处理一个输入流、输出一个流的简单情况。一旦涉及:
- 多个输入文件叠加(水印、画中画)
- 分流:同一个视频要走两条不同处理路径
- 合流:把两个视频拼在一起、把两路音频混在一起
- 视频和音频在同一条滤镜图里处理(比如调速要同时改 setpts 和 atempo)
就必须用 -filter_complex。它支持任意复杂的有向无环图。
同一个流分两路
比如既要原始视频,又要缩小版做画中画:
ffmpeg -i input.mp4 -filter_complex \
"[0:v]split=2[v1][v2];[v2]scale=320:240[pip];[v1][pip]overlay=W-w-10:H-h-10[v]" \
-map "[v]" output.mp4
split=2 把输入复制成两路 [v1] 和 [v2],第二路缩小后叠回第一路。
视频音频一起调速
ffmpeg -i input.mp4 -filter_complex \
"[0:v]setpts=2.0*PTS[v];[0:a]atempo=0.5[a]" \
-map "[v]" -map "[a]" output.mp4
视频慢动作(setpts 改时间戳)和音频减速(atempo=0.5)必须在同一个 filtergraph 里,否则只能用 -vf 和 -af 分开写,效果一样但没法用标签引用。
五、常用流引用写法
| 写法 | 含义 |
|---|---|
[0:v] | 第 0 个输入的视频流(v=video) |
[0:a] | 第 0 个输入的音频流(a=audio) |
[0:s] | 第 0 个输入的字幕流 |
[0:v:0] | 第 0 个输入的第 0 条视频流 |
[1:v] | 第 1 个输入的视频流 |
[label] | 自己命名的中间结果 |
六、避坑清单
- 逗号和分号别搞混:逗号是串行连接,分号是并行链。绝大多数报错都是把分号写成逗号。
- 标签要闭合:每条输入标签必须有来源,每条输出标签要么被下游引用,要么被
-map引用,否则报错”Output with label … does not exist”或”Some filters were not used”。 - 引号要配对:Windows PowerShell 里用双引号包住整个 filtergraph,内部用单引号或转义;bash 里同理。
- 视频滤镜不能处理音频,音频滤镜不能处理视频。如果滤镜收到类型不匹配的流,会报”Cannot find a matching input pad”。
- 顺序很重要:滤镜从左到右执行,
scale,crop和crop,scale结果不同。先想清楚数据流方向。
Tip看不懂复杂滤镜图时,拿笔按分号拆成一条链子,再按逗号拆成单个滤镜,画出标签的流向,就跟看流程图一样。后续四章会反复用这套语法,每次只加一两个新滤镜,不会一下子堆满。