46610号小行星

46610号小行星

如何利用FFmpeg给视频添加水印?

引言#

最近工作中遇到一个需求,需要给大量的视频批量添加水印,试了试网上现有的各种添加水印的程序,有的需要付费,有的又不支持脚本。其实,众所周知,大部分的商业视频处理程序都或多或少利用到了 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 过滤器实现的

Drawtext doc

我介绍几个有用的参数

  • 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

效果
截屏 2023-05-13 17.53.25.png

可以看到颜色、位置、字体、透明度都达到了自定义

图片水印#

图片水印的实现方式是通过 movieoverlay 两个参数来实现

以下举一个例子

ffmpeg -i input.mp4 -vf "movie=watermark.jpg[wm];[in][wm]overlay=20:20[out]" output.mp4

效果

截屏 2023-05-13 18.03.16.png

照片似乎有点大,我们该怎么处理呢?
这时候就要应用到前面的过滤器链来处理
我们利用 scale 来缩放

ffmpeg -i input.mp4 -vf "movie=watermark.jpg,scale=50:50[wm];[in][wm]overlay=20:20[out]" output.mp4

截屏 2023-05-13 18.07.02.png

好像照片又会遮挡到画面,那么该怎么办呢?
那这个时候就让它变透明吧!
首先利用 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

截屏 2023-05-13 18.16.06.png

不过话说回来,为什么不一开始就使用透明的 png 图片来合成呢?哈哈,那样貌似更方便一些

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。