FFmpeg中overlay濾鏡用法-水印及畫中畫


本文為作者原創,轉載請注明出處:https://www.cnblogs.com/leisure_chn/p/10434209.html

1. overlay 技術簡介

overlay 技術又稱視頻疊加技術。overlay 視頻技術使用非常廣泛,常見的例子有,電視屏幕右上角顯示的電視台台標,以及畫中畫功能。畫中畫是指在一個大的視頻播放窗口中還存在一個小播放窗口,兩個窗口不同的視頻內容同時播放。

overlay 技術中涉及兩個窗口,通常把較大的窗口稱作背景窗口,較小的窗口稱作前景窗口,背景窗口或前景窗口里都可以播放視頻或顯示圖片。FFmpeg 中使用 overlay 濾鏡可實現視頻疊加技術。

overlay 濾鏡說明如下:

描述:前景窗口(第二輸入)覆蓋在背景窗口(第一輸入)的指定位置。

語法:overlay[=x:y[[:rgb={0, 1}]]
    參數 x 和 y 是可選的,默認為 0。
    參數 rgb 參數也是可選的,其值為 0 或 1,默認為 0。

參數說明:
    x                   從左上角的水平坐標,默認值為 0
    y                   從左上角的垂直坐標,默認值為 0
    rgb                 值為 0 表示輸入顏色空間不改變,默認為 0;值為 1 表示將輸入的顏色空間設置為 RGB

變量說明:如下變量可用在 x 和 y 的表達式中
    main_w 或 W          主輸入(背景窗口)寬度
    main_h 或 H          主輸入(背景窗口)高度
    overlay_w 或 w       overlay 輸入(前景窗口)寬度
    overlay_h 或 h       overlay 輸入(前景窗口)高度

overlay 濾鏡相關參數示意圖如下:
overlay_filter

2. 命令行用法

可先參考 "FFmpeg 使用基礎" 了解 FFmpeg 命令行基本用法。

overlay 命令行基本格式如下:

ffmpeg -i input1 -i input2 -filter_complex overlay=x:y output

input1 是背景窗口輸入源,input2 是前景窗口輸入源。

2.1 視頻中疊加圖標

背景窗口視頻素材下載(右鍵另存為):ring.mp4
ring.mp4
視頻分辨率是 768x432(此分辨率適用於平板電腦,寬高比為 16:9),上下黑邊的像素高度是 56,播放時長為 37.97 秒。關於分辨率與黑邊的相關內容可參考如下:
為什么很多人把視頻上下加黑條當做“電影感”?
用於編碼視頻文件的視頻預設

前景窗口圖標素材下載(右鍵另存為):ring_100x87.png
ring.png
圖標分辨率是 100x87。圖標格式為 PNG 格式,當然選用其他格式的圖片作圖標也是可以的,但 PNG 圖標具有透明背景,更適合用作圖標。

2.1.1 直接疊加圖標

將圖標疊加於視頻右上角:("-max_muxing_queue_size" 參數的使用見參考資料[3])

ffmpeg -i ring.mp4 -i ring_100x87.png -filter_complex overlay=W-w:56 -max_muxing_queue_size 1024 ring_logo_t.mp4

效果如下:
ring_logo_t.jpg

將圖標疊加於視頻右下角:

ffmpeg -i ring.mp4 -i ring_100x87.png -filter_complex overlay=W-w:H-h-56 -max_muxing_queue_size 1024 ring_logo_b.mp4

效果如下:
ring_logo_b.jpg

2.1.2 延時疊加圖標

如下,背景窗口播放 8.6 秒后,圖標開始顯示。注意 “-itsoffset 8.6” 作為第二個輸入文件的輸入選項,參數位置不能放錯。

ffmpeg -i ring.mp4 -itsoffset 8.6 -i ring_100x87.png -filter_complex overlay=W-w:56 -max_muxing_queue_size 1024 ring_logo_delay.mp4

2.2 視頻中疊加視頻——畫中畫

視頻中疊加視頻即為畫中畫功能。注意兩個視頻僅圖像部分會疊加在一起,聲音是不會疊加的,有一個視頻的聲音會消失。

2.2.1 疊加計時器

找一個計時器小視頻,將之疊加到背景視頻上。我們可以從測試源中獲取這個計時器視頻。先運行如下命令:

ffplay -f lavfi -i testsrc

視頻無法貼在本文里,那運行截圖命令,從視頻中截取一張圖:

ffmpeg -ss 00:00:12 -f lavfi -i testsrc -frames:v 1 -f image2 testsrc.jpg

效果如下:
testsrc.jpg

我們把計時器那一小塊視頻裁剪下來,運行如下命令:

ffmpeg -ss 00:00:10 -t 20 -f lavfi -i testsrc -vf crop=61:52:224:94 timer.h264

此命令主要用到了 crop 視頻濾鏡,說明一下:
"-vf crop=61:52:224:94" 表示裁剪一塊位於 (224,94) 坐標處寬為 61 像素高為 52 像素的視頻塊
"-ss 00:00:10 -t 20" 表示從 10 秒處開始裁剪,裁剪時長為 20 秒

將計時器視頻 timer.h264 疊加到背景視頻 ring.mp4 里:

ffmpeg -i ring.mp4 -i timer.h264 -filter_complex overlay=W-w:0 -max_muxing_queue_size 1024 ring_timer.mp4

效果如下:
ring_timer.jpg

看一下視頻疊加過程中 FFmpeg 在控制台中的打印信息,關注流的處理:

$ ffmpeg -i ring.mp4 -i timer.h264 -filter_complex overlay=W-w:0 -max_muxing_queue_size 1024 ring_timer.mp4
......
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'ring.mp4':
  Metadata:
    ......
  Duration: 00:00:37.97, start: 0.032000, bitrate: 515 kb/s
    Stream #0:0(chi): Video: h264 (avc1 / 0x31637661), none, 768x432, 488 kb/s, 23 fps, 23 tbr, 23k tbn, 46k tbc (default)
    Metadata:
      handler_name    : 1348358526.h264#video:fps=23 - Imported with GPAC 0.5.1-DEV-rev4127
    Stream #0:1(chi): Audio: aac (HE-AAC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 95 kb/s (default)
    Metadata:
      handler_name    : GPAC ISO Audio Handler
Input #1, h264, from 'timer.h264':
  Duration: N/A, bitrate: N/A
    Stream #1:0: Video: h264 (High 4:4:4 Predictive), yuv444p(progressive), 61x52 [SAR 1:1 DAR 61:52], 25 fps, 25 tbr, 1200k tbn, 50 tbc
Stream mapping:
  Stream #0:0 (h264) -> overlay:main (graph 0)
  Stream #1:0 (h264) -> overlay:overlay (graph 0)
  overlay (graph 0) -> Stream #0:0 (libx264)
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
......

看 "Stream mapping" 部分可以看出:
輸入源 1 視頻流 "Stream #0:0" 和輸入源 2 視頻流 "Stream #1:0" 疊加到輸出視頻流 "Stream #0:0"
輸入源 1 音頻流 "Stream #0:1" 拷貝到輸出音頻流 "Stream #0:1"

視頻開始幾秒處播放有些異常,聲音播放幾秒后圖像才開始播放,原因不太清楚。

3. API用法

使用濾鏡API編程,解析不同的濾鏡選項,以達到和命令行中輸入命令同樣的效果。

例程使用 "FFmpeg 濾鏡 API 用法與實例解析" 中第 4.2 節的示例程序,運行如下命令下載例程源碼:

svn checkout https://github.com/leichn/exercises/trunk/source/ffmpeg/ffmpeg_vfilter

下載之后進入源碼目錄,編譯生成 vf_file 可執行文件:

cd ffmpeg_vfilter
make vf_file

運行如下命令進行測試:

./vf_file ring.flv -vf "movie=ring_100x87.png[logo];[in][logo]overlay=W-w:56"

測試效果為:
ring_logo_t.jpg
因為例程尚不支持多輸入的方式,所以上述測試命令中借助了 movie 濾鏡來加載第二個輸入,這條命令和下面這條命令效果是一樣的

ffplay ring.mp4 -i ring_100x87.png -filter_complex overlay=W-w:56

4. 遺留問題

第 3 節例程不支持多輸入方式,借助了 movie 濾鏡變通實現,多輸入情況下 API 如何編程?待分析如下命令中多輸入選項的解析處理方式:

ffplay ring.mp4 -i ring_100x87.png -filter_complex overlay=W-w:56

5. 參考資料

[1] 為什么很多人把視頻上下加黑條當做“電影感”?
[2] 用於編碼視頻文件的視頻預設
[3] Too many packets buffered for output stream

6. 修改記錄

2019-02-16 V1.0 首次整理
2020-01-17 V1.0 修改資源文件下載地址錯誤
2020-02-23 V1.0 github 文件下載地址規則改變,修改資源文件無法下載問題


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM