引言#
最近工作中遇到一个需求,需要给大量的视频批量添加水印,试了试网上现有的各种添加水印的程序,有的需要付费,有的又不支持脚本。其实,众所周知,大部分的商业视频处理程序都或多或少利用到了 FFmpeg 来帮助实现功能,因此我决定直接使用 FFmpeg 来给视频添加水印,这样子也可以很方便地书写 bash 脚本来批处理。顺带一提,某些利用 FFmpeg 的商业程序并不遵循其开源协议,真是可恶啊!
下载与安装#
macOS/Linux 直接使用包管理工具安装就可以
Windows 则在 FFmepg 下载 处下载就可以了
具体就不再赘述了
使用#
FFmpeg 使用起来非常简单
-i
指定输入的文件
末尾指定输出的文件
ffmpeg -i input.mp4 output.avi
即意味着把 mp4 格式的视频转换为 avi 格式
还可以通过-c:v
参数来指定视频编码器的格式,默认为 h264 编码
这只是最常用的视频格式转换,但我们需要的是添加水印
FFmepg 提供了一个参数选项 -fliter
被称作过滤器或滤波器,通过这个参数可以实现裁剪、旋转、改变图像分辨率、添加滤镜等功能
在 FFmpeg 中有两种类型的 fliter,一种是简单型的,一种是复杂性的,简单型只支持单输入单输出的情形,而复杂性则因为其不是简单的线性处理而支持多输入多输出。
通常而言,简单型的处理速度会比较快,其解码相关的帧处理后重新编码。
_________ ______________
| | | |
| decoded | | encoded data |
| frames |\ _ | packets |
|_________| \ /||______________|
\ __________ /
simple _\|| | / encoder
filtergraph | filtered |/
| frames |
|__________|
同时,过滤器之间也可以线性叠加,一个过滤器的输出成为另一个过滤器的输入从而形成一个过滤器链
-vf
和 -af
分别代表着视频和音频过滤器的参数
例如
ffmpeg -i input.mp4 -c:v libx264 -vf "transpose=2" output.mp4
则代表着将主视频轨逆时针旋转 90 度
通过-vf
参数之间添加逗号即可形成过滤器链
类似 transpose 的过滤器还有很多,在 FFmepg fliters doc 中可以看到大约仅视频过滤器就有近 300 种
添加水印#
添加水印的种类我大致分为两类
- 文字水印
- 图片水印
而这两种水印添加时又要考虑水印添加的内容、位置、水印大小、透明度等
接下来我一个一个说明
文字水印#
文字水印的实现方式是通过 drawtext
过滤器实现的
我介绍几个有用的参数
- fontsize (字体大小)
- fontfile (字体)
- text (文字)
- x (x 坐标)
- y (y 坐标)
- fontcolor (文字颜色)
- alpha (透明度)
我准备用以下指令测试一下
ffmpeg -i input.mp4 -vf "drawtext=fontsize=100:fontfile=Arial.ttf:text='水印':x=20:y=20:fontcolor=red:alpha=0.5" output.mp4
效果
可以看到颜色、位置、字体、透明度都达到了自定义
图片水印#
图片水印的实现方式是通过 movie
与 overlay
两个参数来实现
以下举一个例子
ffmpeg -i input.mp4 -vf "movie=watermark.jpg[wm];[in][wm]overlay=20:20[out]" output.mp4
效果
照片似乎有点大,我们该怎么处理呢?
这时候就要应用到前面的过滤器链来处理
我们利用 scale
来缩放
ffmpeg -i input.mp4 -vf "movie=watermark.jpg,scale=50:50[wm];[in][wm]overlay=20:20[out]" output.mp4
好像照片又会遮挡到画面,那么该怎么办呢?
那这个时候就让它变透明吧!
首先利用 format
把图像转换到含有 alpha 通道的像素格式,再通过指定混合来实现
ffmpeg -i input.mp4 -vf "movie=watermark.jpg,scale=200:200,format=yuva444p,colorchannelmixer=aa=0.5[wm];[in][wm]overlay=20:20[out]" output.mp4
不过话说回来,为什么不一开始就使用透明的 png 图片来合成呢?哈哈,那样貌似更方便一些