导读:本期聚焦于辉辉创作的《FFmpeg怎么给视频加图片或文字水印并精确控制位置?》,敬请观看详情。视频发布到公开平台前加上自有标识,能有效防止被随意盗用。FFmpeg通过滤镜图机制,可在不重新编码全部画面的情况下叠加图层。图片水印依赖overlay滤镜读取本地文件,坐标用x与y表达式定位;文字水印则由drawtext调用字体文件渲染,支持动态时间码。位置控制不只是填数字,还能用main_w等变量做百分比布局,避免不同分辨率错位。理解滤镜链顺序与基准画布概念,才能把logo稳定放在右下角或随滚动字幕移动,同时把画质损失压到最低。

FFmpeg怎么给视频加图片或文字水印并精确控制位置?

FFmpeg给视频添加图片或文字水印,如何精确控制位置?

在日常的视频制作和内容分发中,给视频加上水印是非常普遍的需求。无论是为了保护版权、展示品牌Logo,还是标注时间、作者信息,水印都起到了重要作用。很多人以为必须用Premiere、Final Cut Pro这类专业软件才能完成,其实只要学会FFmpeg的命令行操作,一条命令就能搞定图片水印和文字水印,还能精确控制它们的位置、大小和透明度。本文将从基础原理讲起,逐步带你掌握FFmpeg的水印技术。

一、图片水印的叠加原理与坐标系统

1.1 overlay滤镜的工作方式

FFmpeg处理图片水印的核心是overlay滤镜。这个滤镜的作用是把一张图片“盖”在视频画面上。要实现这个效果,FFmpeg需要同时接收两路输入:一路是视频流,另一路是图片流。在滤镜图中,我们用方括号加数字来标记不同的流,比如[0:v]表示第一个输入文件(通常是视频)的视频流,[1:v]表示第二个输入文件(图片)的视频流。overlay滤镜会把第二个流绘制到第一个流之上,然后输出一个新的视频流。

位置的控制由xy两个参数决定,默认值是0,也就是图片的左上角与视频画面的左上角对齐。如果直接写死数值,比如x=100:y=200,那么水印就会固定出现在距离左边100像素、上边200像素的位置。但这种写法有一个明显的缺点:当视频的分辨率发生变化时,水印的相对位置也会改变,很可能跑到画面中间甚至外面去。

1.2 坐标系统与动态变量

FFmpeg的坐标系统原点在左上角,向右为x正方向,向下为y正方向。为了让水印在不同分辨率下都能保持在理想位置,我们需要使用内置变量。常用的变量有:

  • main_w:主画面(视频)的宽度
  • main_h:主画面(视频)的高度
  • overlay_w:水印图片的宽度
  • overlay_h:水印图片的高度

假设你想让水印始终位于右下角,并且距离右边和下边各20像素,那么x和y的表达式应该是:

x = main_w - overlay_w - 20
y = main_h - overlay_h - 20

这样不管视频是1920×1080还是1280×720,水印都会紧贴右下角,保持相同的边距。同理,如果要放在左下角,可以写成x=20:y=main_h-overlay_h-20;放在右上角则是x=main_w-overlay_w-20:y=20

1.3 完整命令示例

下面是一条完整的命令,将名为logo.png的图片水印添加到input.mp4的右下角,并输出为output.mp4

ffmpeg -i input.mp4 -i logo.png -filter_complex \
"[0:v][1:v]overlay=x=main_w-overlay_w-20:y=main_h-overlay_h-20" \
-c:a copy output.mp4

这里有几个要点需要说明。首先,-filter_complex后面跟着滤镜图描述,它允许我们处理多个输入流。其次,-c:a copy表示音频流直接复制,不做重新编码,这样可以大幅提高处理速度,同时保证音质无损。最后,如果水印图片是PNG格式且带有透明通道,overlay会保留透明度,水印看起来就像浮在视频上一样;如果是JPEG这种没有透明度的格式,图片的矩形区域会完全遮挡住下面的视频内容,效果就不太理想了。

二、文字水印的drawtext滤镜配置

2.1 drawtext的基本用法

文字水印不能使用overlay滤镜,而是要用drawtext滤镜。这个滤镜直接在视频帧上渲染文本,相当于在每一帧画面上写字。使用drawtext时必须指定字体文件,因为FFmpeg本身不携带字体,需要依赖系统已有的字体库。在Linux系统中,常见的字体路径是/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf;在Windows上则是C:\Windows\Fonts\arial.ttf。如果你的字体路径中包含空格或特殊字符,需要用引号括起来。

文字的内容通过text参数传入,例如text='Hello World'。也可以使用textfile参数读取外部文本文件,适合需要大量文字的场景。此外,还可以使用格式化字符串,比如%{pts:hms}表示当前播放时间(时:分:秒格式),这在录制屏幕或直播回放时非常有用。

2.2 位置控制与时间变量

文字水印的位置同样由xy控制,并且支持更多动态表达式。除了前面提到的main_wmain_h,还有tw(文字宽度)和th(文字高度)这两个变量。例如,要让文字固定在右上角,可以写成:

x = w - tw - 10
y = 10

其中wh是当前视频帧的宽度和高度,与main_wmain_h等效。

更高级的用法是利用时间变量t(当前时间,单位为秒)实现滚动或闪烁效果。比如让文字从右向左水平滚动:

x = w - mod(t * 100, w + tw)

这里的mod函数取模运算,使得文字不断循环移动。注意,在滤镜表达式中,冒号和逗号有特殊含义,如果要在文字内容中使用它们,需要用反斜杠转义,比如text='Time\: now'

2.3 中文文字与样式美化

中文文字水印需要特别注意字体文件的支持。如果使用的字体不包含中文字形,渲染出来的就会是乱码或方框。因此建议使用像“微软雅黑”、“思源黑体”这样的中文字体。在某些环境中,还需要加上text_shaping=1参数来启用文字整形,确保复杂排版(如竖排文字)正确显示。

为了让文字在亮色背景下更清晰,可以使用box参数添加背景框。例如box=1:boxcolor=black@0.5会在文字背后绘制一个半透明的黑色矩形,大大提升可读性。字体颜色可以用fontcolor指定,支持十六进制颜色码或颜色名称,比如fontcolor=whitefontcolor=#FF0000。字体大小用fontsize控制,单位是像素。

下面是一个在视频左上角显示当前时间码的例子:

ffmpeg -i input.mp4 -vf \
"drawtext=fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf:\
text='%{pts:hms}':x=10:y=10:fontsize=24:fontcolor=white:box=1:boxcolor=black@0.5" \
-c:a copy output.mp4

三、多水印组合与性能优化策略

3.1 同时添加图片和文字水印

实际业务中经常需要既放Logo又加版权文字。FFmpeg允许在一条filter_complex中串联多个滤镜。思路是先对原始视频应用overlay添加图片,得到中间结果,然后再对这个中间结果应用drawtext添加文字。中间结果需要用方括号别名标记,以便后续滤镜引用。

典型的写法如下:

ffmpeg -i input.mp4 -i logo.png -filter_complex \
"[0:v][1:v]overlay=x=main_w-overlay_w-30:y=main_h-overlay_h-30[v1];\
[v1]drawtext=fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf:\
text='Copyright www.bbccb.com':x=(w-text_w)/2:y=main_h-th-20:fontsize=20:fontcolor=yellow[v2]" \
-map "[v2]" -map 0:a -c:a copy -c:v libx264 -crf 20 output.mp4

这条命令做了以下几件事:首先将logo.png叠加到视频右下角,输出命名为[v1];然后对[v1]添加文字“Copyright www.bbccb.com”,文字水平居中(x=(w-tw)/2),垂直位于底部上方20像素(y=main_h-th-20),输出命名为[v2]。最后用-map明确选择处理后的视频流[v2]和原始音频流0:a,避免滤镜图输出干扰默认流选择。

3.2 条件显示与动态布局

有时我们希望水印只在视频的前几秒出现,或者只在特定时间段显示。这可以通过enable表达式实现。例如,只在视频前10秒显示图片水印:

overlay=x=...:y=...:enable='lt(t,10)'

lt(t,10)表示时间t小于10秒时为真。同样,drawtext也支持enable参数。

对于竖屏和横屏混合的素材,可以结合if表达式判断视频方向。比如检测到高度大于宽度(竖屏)时,将水印放在顶部中央;否则放在右下角。虽然命令行写起来有点长,但本质上就是一段脚本化的逻辑。

3.3 性能优化技巧

添加水印通常不会改变视频的分辨率和帧率,所以编码时可以尽量保持画质。推荐使用-c:v libx264 -crf 18,CRF值越低质量越高,18~22是比较平衡的范围。音频直接复制即可(-c:a copy)。

当处理4K超高清视频时,水印图片的缩放计算可能会成为性能瓶颈。解决办法是在传入overlay之前,先将水印图片缩放到合适的尺寸。例如,先用scale滤镜把logo缩小到视频宽度的10%,再叠加:

[1:v]scale=iw*0.1:-1[logo]; [0:v][logo]overlay=...

另外,使用-preset veryfast可以大幅缩短编码时间,同时画质损失肉眼几乎不可察觉。如果机器性能足够,也可以用-preset medium获得更好的压缩效率。

四、常见问题与排查方法

4.1 水印位置不对或超出画面

最常见的原因是坐标表达式写错了。比如忘了减去水印自身的宽高,导致水印一部分跑到画面外面。建议先在命令行中打印出视频的宽高信息(用ffprobe),然后手动计算预期坐标,再对比实际效果。另外,注意变量名的大小写,main_wMAIN_W是不同的。

4.2 文字显示为方框或乱码

这几乎都是字体问题。要么字体路径不正确,要么字体不支持中文字符。可以先测试一个英文字符,如果正常显示,再换成中文。确保字体文件存在且可读,必要时使用绝对路径。在Windows上,路径中的反斜杠需要写成双反斜杠或者用正斜杠。

4.3 水印闪烁或抖动

如果水印图片本身带有半透明区域,而视频又是可变帧率,可能会出现闪烁。可以尝试将水印图片转换为固定尺寸,并在overlay中加上format=rgba强制使用RGBA色彩空间。另外,确保输入视频的帧率稳定,必要时用-r参数固定输出帧率。

4.4 处理速度极慢

如果发现编码速度远低于实时,可能是因为开启了过多的滤镜或使用了高CRF值。可以尝试降低CRF到23~28,或者使用硬件加速编码(如-c:v h264_nvenc)。另外,检查是否无意中改变了分辨率或帧率,不必要的重采样会拖慢速度。

五、总结

通过本文的学习,你应该已经掌握了FFmpeg添加图片水印和文字水印的核心方法。关键在于理解overlay和drawtext两个滤镜的参数含义,以及熟练运用坐标变量实现自适应定位。多水印组合时注意滤镜链的串联写法,性能优化则围绕编码参数和预处理展开。只要多加练习,即使面对复杂的业务需求,也能用一条简洁的命令完成高质量的水印添加,无需依赖昂贵的商业软件。

FFmpegwatermarkvideo_processing修改时间:2026-08-21 00:16:32

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。