提示

返回博客列表

FFmpeg filter_complex 实战:画中画、拼接、水印与调色的完整工作流

FFmpeg filter_complex 实战:画中画、拼接、水印与调色的完整工作流

很多同学用 FFmpeg 只会 -i in.mp4 out.mp4 转个封装,一旦要"把两段视频叠在一起""给成片加 Logo""批量打水印""统一调色",就只能在网上到处抄命令,改一个参数就满屏报错。这篇文章把 -filter_complex 的完整工作流拆开讲透,让你遇到这类需求能自己拼出命令。

一、为什么需要 filter_complex

单路简单滤镜 -vf(等价于 -filter:v)只能处理"一条输入流 → 一条输出流",而且只能串一条滤镜链。当你需要:

  • 把两个视频叠加(画中画);
  • 把多条流拼接成一条;
  • 在同一画面里同时做缩放、裁剪、水印、调色;

就必须用 -filter_complex,它支持多条输入/输出滤镜图(filtergraph)带标签的链路

经验法则:只要输入或输出不止一路,或者要在一条命令里同时改画面和声音,就用 -filter_complex

二、滤镜语法基础

2.1 简单滤镜 -vf

ffmpeg -i in.mp4 -vf "scale=1280:720" out.mp4

滤镜之间用逗号分隔:scale=1280:720,eq=brightness=0.05

2.2 复杂滤镜 -filter_complex

语法是 [输入][输入]滤镜=参数[输出]

ffmpeg -i main.mp4 -i sub.mp4 -filter_complex "[1:v]scale=480:-1[pip];[0:v][pip]overlay=W-w-20:20" -map "[v]" out.mp4

要点:

  • [0:v] 表示第一个输入文件的视频流,[1:a] 表示第二个输入文件的音频流;
  • [pip] 是自定义的临时标签,分号 ; 分隔多条滤镜链;
  • 最后的 -map "[v]" 指定把哪条输出写进结果文件;
  • 如果忘了 -map,FFmpeg 会按默认规则选流,常常选错,务必显式 -map

下面这张表是本文用到的核心滤镜:

滤镜 作用 典型参数
scale 缩放分辨率 scale=1280:720 / scale=-1:720
overlay 叠加(画中画) overlay=W-w-20:20
concat 拼接多条流 concat=n=2:v=1:a=1
drawtext 文字水印 text='VidDown':fontsize=24
crop 裁剪 crop=in_w:in_h-100:0:0
eq 亮度/对比/饱和 eq=brightness=0.06:contrast=1.1
hue 色相 hue=h=30
pad 加边填充 pad=iw+40:ih+40:20:20

三、实战一:画中画(PiP)

最经典的"主画面 + 右下角小窗"效果:

ffmpeg -i main.mp4 -i sub.mp4 -filter_complex ^
  "[1:v]scale=480:-1[pip];[0:v][pip]overlay=W-w-20:20" ^
  -map "[v]" -map "0:a" -c:a copy out.mp4

注意 -map "0:a" 直接拷贝主视频的音轨,避免重编码声音。

3.1 动态位置表达式

overlay 支持 main_wmain_hoverlay_woverlay_h 四个内置变量,分别表示主画面和叠加层的宽高,因此:

  • 右上角:overlay=W-w-20:20
  • 居中:overlay=(W-w)/2:(H-h)/2
  • 跟随底部滚动字幕区:overlay=20:H-h-80

3.2 圆形遮罩小窗

把小窗裁成圆角,可叠加 format=rgba,geq 或先用 mask 预生成 PNG 再 overlay,生产环境更推荐用一张带透明通道的圆形蒙版 PNG 做 overlay,性能更稳。

四、实战二:多段视频拼接

有两种主流做法。

4.1 concat 滤镜(需参数一致)

ffmpeg -i a.mp4 -i b.mp4 -filter_complex ^
  "[0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1[v][a]" ^
  -map "[v]" -map "[a]" out.mp4

要求两段视频分辨率、编码、帧率一致,否则会花屏或卡顿。

4.2 concat demuxer(推荐,避免重编码)

新建 list.txt

file 'a.mp4'
file 'b.mp4'
file 'c.mp4'
ffmpeg -f concat -safe 0 -i list.txt -c copy out.mp4

-c copy 直接拼接,速度快、不损画质,但前提仍是编码参数一致。参数不一致时先统一转码再拼。

五、实战三:批量加水印

5.1 drawtext 文字水印

ffmpeg -i in.mp4 -vf ^
  "drawtext=text='VidDown':fontcolor=white@0.6:fontsize=24:^
   x=w-tw-20:y=h-th-20:box=1:boxcolor=black@0.3:boxborderw=4" ^
  out.mp4

white@0.6 表示白色 60% 不透明度;box=1 给文字加半透明底框,提升在亮背景上的可读性。

单角 Logo:

ffmpeg -i in.mp4 -i logo.png -filter_complex "overlay=20:20" out.mp4

四角平铺防盗水印:用 tile 或多次 overlay 复制标签,再分别定位到四个角。批量处理建议写成脚本遍历目录:

for f in *.mp4; do
  ffmpeg -i "$f" -i logo.png -filter_complex "overlay=20:20" "wm_$f"
done

六、实战四:调色与基础校正

统一的观感往往靠 eq 即可:

ffmpeg -i in.mp4 -vf "eq=brightness=0.06:contrast=1.1:saturation=1.2" out.mp4
  • brightness:亮度,±1 之间,0.05 左右最自然;
  • contrast:对比度,1.0 为原值;
  • saturation:饱和度,1.2 更鲜艳;
  • 色相偏移用 hue=h=30(角度)。

需要进一步风格化(电影感 LUT)可用 lut3d 加载 .cube 调色文件:

ffmpeg -i in.mp4 -vf "lut3d=file=teal_orange.cube" out.mp4

七、性能与硬件加速注意点

  1. 滤镜默认在 CPU 上逐帧计算,开销大;若用 NVIDIA 显卡,用 hwupload_cuda 把帧上传显存再接 scale_cudaoverlay_cuda
  2. scale 放在滤镜链最前面,先缩小数据量再叠加/调色,能显著省 CPU。
  3. 编码侧用 -preset veryfast -crf 23 平衡速度与体积。
  4. drawtext 会对每帧重绘文字,开启其内置缓存可降开销;大量静态水印场景可考虑先烧录一次再批量。

八、排错清单

现象 可能原因 排查办法
输出没有声音 漏写 -map 音轨 显式 -map "[a]"-map 0:a
画中画位置错乱 overlay 坐标用了固定像素 改用 W-w-20 等相对变量
拼接后花屏 两段参数不一致 先统一转码再 concat
滤镜链报 No such filter 编译未带该滤镜 ffmpeg -filters 查是否支持
中文水印乱码 缺字体 fontfile= 指定中文字体路径

九、小结

-filter_complex 不是黑魔法,本质就是"给每一路流贴标签、用滤镜链描述变换、最后 -map 选输出"。掌握 scale / overlay / concat / drawtext / eq 这五个,就能覆盖 80% 的视频后期自动化需求。把它们写成脚本,配合 VidDown 的批量处理能力,就能把重复的视频加工变成一键任务。

想亲手试试?用 VidDown 一键解析下载

粘贴视频链接即可解析,多平台支持、网页端即用;下载桌面客户端解锁海外平台本地解析,开通会员更享不限次下载。

顶部