本文爲做者原創,轉載請註明出處:http://www.javashuo.com/article/p-efrrvaaz-bs.htmlhtml
overlay技術又稱視頻疊加技術。overlay視頻技術使用很是普遍,常見的例子有,電視屏幕右上角顯示的電視臺臺標,以及畫中畫功能,畫中畫是指在一個大的視頻播放窗口中還存在一個小播放窗口,兩個窗口不一樣的視頻內容同時播放。git
overlay技術中涉及兩個窗口,一般把較大的窗口稱做背景窗口,較小的窗口稱做前景窗口,背景窗口或前景窗口裏均可以播放視頻或顯示圖片。FFmpeg中使用overlay濾鏡可實現視頻疊加技術。github
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濾鏡相關參數示意圖以下:
api
可先參考「FFmpeg使用基礎」瞭解命令行用法基礎app
overlay命令行基本格式以下:ide
ffmpeg -i input1 -i input2 -filter_complex overlay=x:y output
input1是背景窗口輸入源,input2是前景窗口輸入源。測試
背景窗口視頻素材下載:ring.mp4
視頻分辨率是768x432(此分辨率適用於平板電腦,寬高比爲16:9),上下黑邊的像素高度是56,播放時長爲37.97秒。關於分辨率與黑邊的相關內容可參考以下:
爲何不少人把視頻上下加黑條當作「電影感」?
用於編碼視頻文件的視頻預設編碼
前景窗口圖標素材下載:ring_100x87.png
圖標分辨率是100x87。圖標格式爲PNG格式,固然選用其餘格式的圖片做圖標也是能夠的,但PNG圖標具備透明背景,更適合用做圖標。命令行
將圖標疊加於視頻右上角
ffmpeg -i ring.mp4 -i ring_100x87.png -filter_complex overlay=W-w:56 -max_muxing_queue_size 1024 ring_logo_t.mp4
效果以下:
將圖標疊加於視頻右下角
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
效果以下:
以下,背景窗口播放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
視頻中疊加視頻即爲畫中畫功能。注意兩個視頻僅圖像部分會疊加在一塊兒,聲音是不會疊加的,有一個視頻的聲音會消失。
找一個計時器小視頻,將之疊加到背景視頻上。咱們能夠從測試源中獲取這個計時器視頻。先運行以下命令:
ffplay -f lavfi -i testsrc
視頻沒法貼在本文裏,那運行截圖命令,從視頻中截取一張圖:
ffmpeg -ss 00:00:12 -f lavfi -i testsrc -frames:v 1 -f image2 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
效果以下:
看一下視頻疊加過程當中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)
視頻開始幾秒處播放有些異常,聲音播放幾秒後圖像纔開始播放,緣由不太清楚。
使用濾鏡API編程,解析不一樣的濾鏡選項,以達到和命令行中輸入命令一樣的效果。
例程使用「FFmpeg濾鏡API用法與實例解析」中第4.2節的示例程序
代碼目錄https://github.com/leichn/exercises/blob/master/source/ffmpeg/ffmpeg_vfilter/
下載代碼,進入代碼目錄,在命令行運行make vf_file
命令,將生成vf_file可執行文件
在命令行運行./vf_file ring.flv -vf "movie=ring_100x87.png[logo];[in][logo]overlay=W-w:56"
測試效果爲:
由於例程尚不支持多輸入的方式,因此上述測試命令中藉助了movie濾鏡來加載第二個輸入,這條命令和下面這條命令效果是同樣的
ffplay ring.mp4 -i ring_100x87.png -filter_complex overlay=W-w:56
第3節例程不支持多輸入方式,藉助了movie濾鏡變通實現,多輸入狀況下API如何編程?待分析以下命令中多輸入選項的解析處理方式:
ffplay ring.mp4 -i ring_100x87.png -filter_complex overlay=W-w:56
[1] 爲何不少人把視頻上下加黑條當作「電影感」?
[2] 用於編碼視頻文件的視頻預設
2019-02-16 V1.0 首次整理