21、添加水印:使用overlay滤镜叠加图片水印、文字水印、时间水印
水印这东西,说白了就是给视频打上专属标记。不管是保护版权,还是品牌露出,甚至只是加个拍摄时间,都离不开它。我在做视频后期处理时,几乎每个项目都会遇到这个需求。
FFmpeg 的 overlay 滤镜,就是干这个的。它能把一张图、一段文字,甚至动态的时间戳,叠加到视频画面上。今天我就带你把它玩透。
21.1 图片水印:最基础的叠加
图片水印是最常见的。比如给视频加上 Logo。
先看一个最简单的命令:
ffmpeg -i input.mp4 -i logo.png -filter_complex "overlay=10:10" output.mp4
这个命令把 logo.png 放在视频的左上角,距离左边和上边各 10 像素。
但实际项目中,我们往往需要更灵活的位置。比如右下角:
ffmpeg -i input.mp4 -i logo.png -filter_complex "overlay=main_w-overlay_w-10:main_h-overlay_h-10" output.mp4
这里用到了几个内置变量:
- main_w:主视频宽度
- main_h:主视频高度
- overlay_w:水印图片宽度
- overlay_h:水印图片高度
嗯,这里要注意:如果你想让水印居中,可以这样写:
overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2
我曾经在做一个批量处理项目时,客户要求水印位置必须精确到像素。当时我直接用硬编码坐标,结果不同分辨率视频全乱了。后来改用变量计算,一劳永逸。
21.2 文字水印:用 drawtext 滤镜
文字水印需要用到另一个滤镜——drawtext。它依赖 libfreetype 库,编译 FFmpeg 时记得带上。
基本用法:
ffmpeg -i input.mp4 -vf "drawtext=text='蓝海资料':fontcolor=white:fontsize=24:x=10:y=10" output.mp4
这会在左上角显示白色文字「蓝海资料」。
但文字水印的坑不少。我列几个常见参数:
| 参数 | 说明 | 示例 |
|---|---|---|
| text | 文字内容 | text='Hello' |
| fontfile | 字体文件路径 | fontfile=/usr/share/fonts/msyh.ttf |
| fontcolor | 字体颜色 | fontcolor=white@0.5 |
| fontsize | 字号 | fontsize=36 |
| box | 是否加背景框 | box=1:boxcolor=black@0.3 |
| shadowx/shadowy | 文字阴影偏移 | shadowx=2:shadowy=2 |
我个人习惯给文字加个半透明背景框,这样在任何画面下都能看清:
ffmpeg -i input.mp4 -vf "drawtext=text='蓝海资料':fontcolor=white:fontsize=28:box=1:boxcolor=black@0.4:x=10:y=10" output.mp4
fontfile=C:/Windows/Fonts/msyh.ttf,别用单反斜杠。
21.3 时间水印:动态显示当前时间
时间水印在监控视频、录屏回放中特别常用。drawtext 支持时间变量,可以实时显示视频的当前时间戳。
核心用法:
ffmpeg -i input.mp4 -vf "drawtext=text='%{localtime}':fontsize=20:fontcolor=white:x=w-tw-10:y=10" output.mp4
%{localtime} 会显示系统本地时间。但注意,这个时间是 FFmpeg 开始处理时的时间,不是视频本身的录制时间。
如果想显示视频的时间进度(从 0 开始),用 %{pts}:
ffmpeg -i input.mp4 -vf "drawtext=text='%{pts\:hms}':fontsize=20:fontcolor=white:x=10:y=h-th-10" output.mp4
%{pts:hms} 会把时间戳格式化成 HH:MM:SS 格式。比如视频播放到 1 分 30 秒时,显示 00:01:30。
你想想看,如果做课程录制,加上时间水印,学员回看时就知道具体时间点,多方便。
更复杂的用法,比如自定义时间格式:
ffmpeg -i input.mp4 -vf "drawtext=text='%{localtime\:%Y-%m-%d %H\\:%M\\:%S}':fontsize=18:fontcolor=yellow:x=10:y=10" output.mp4
这里用 \\: 转义冒号,因为 FFmpeg 的文本解析中冒号有特殊含义。
21.4 组合使用:图片+文字+时间一起上
实际项目中,往往需要同时叠加多个水印。比如左上角放 Logo,右下角显示时间,底部再跑一行滚动字幕。
用 filter_complex 可以串联多个滤镜:
ffmpeg -i input.mp4 -i logo.png -filter_complex \
"[0:v][1:v]overlay=10:10[bg]; \
[bg]drawtext=text='蓝海资料':fontcolor=white:fontsize=20:x=10:y=50[bg2]; \
[bg2]drawtext=text='%{localtime}':fontcolor=yellow:fontsize=16:x=w-tw-10:y=10" \
output.mp4
这里用 [bg]、[bg2] 作为中间标签,把处理结果一步步传递下去。说白了就是流水线作业。
21.5 知识体系图
下面这张图,帮你理清 overlay 水印的核心逻辑:
21.6 避坑指南与实用技巧
做水印叠加,有几个坑我不得不提:
- 字体找不到: 用 drawtext 时,如果字体路径不对,FFmpeg 会报错。建议先用
fc-list查看系统可用字体。 - 性能问题: 叠加多个水印会消耗更多 CPU。如果只是加一个静态图片水印,用
-vf比-filter_complex更轻量。 - 透明背景: 图片水印最好用 PNG 格式,支持透明通道。JPG 会有白色背景,很难看。
- 时间水印的时区:
%{localtime}用的是系统时区。如果视频是在不同时区录制的,记得先设置TZ环境变量。
好了,水印叠加的内容就这些。从图片到文字,再到动态时间,你都能用 overlay 和 drawtext 搞定。下次遇到加 Logo 或者打时间戳的需求,直接上命令就行。
公众号:蓝海资料掘金营,微信deep3321