46610号小行星

46610号小行星

如何利用FFmpeg給視頻添加水印?

Introduction#

最近工作中遇到一個需求,需要給大量的視頻批量添加水印,試了試網上現有的各種添加水印的程式,有的需要付費,有的又不支援腳本。其實,眾所周知,大部分的商業視頻處理程式都或多或少利用到了 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 圖片來合成呢?哈哈,那樣貌似更方便一些

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。