背景
很簡單的需求:我需要將一個gif
嵌入到視頻裏面的指定位置,並要指定時間播放;
環境
windows11 64位專業版
ffmpeg version 2022-04-07-git-607ecc27ed-full_build-www.gyan.dev Copyright (c) 2000-2022 the FFmpeg developers
輸入:input.mp4(6秒), 1.gif(1.24秒)
第一版:先將gif嵌入指定位置
ffmpeg -i input.mp4 -stream_loop -1 -i 1.gif -filter_complex "[0:v][1:v] overlay=10:10:shortest=1" output1.mp4 -y
參數釋義:
-stream_loop -1
:-1 表示 GIF 文件無限循環播放。也可以指定播放次數,如:2,播放兩次;-i 1.gif
:設置1.gif
作爲第二個輸入文件。-filter_complex "[0:v][1:v] overlay=10:10:shortest=1"
:設置一個複雜濾鏡。此濾鏡將 GIF 文件(第二個輸入,即[1:v]
)疊加到視頻文件(第一個輸入,即[0:v]
)上。疊加的位置在座標(10,10)
上。shortest=1
表示當任何一路輸入結束時,輸出也將結束。output1.mp4 -y
:將結果輸出到output1.mp4
。如果文件已存在,-y
選項會直接覆蓋它。
運行結果:沒有問題,gif被嵌入到指定位置,並正常播放;
注意:shortest=1 參數如果沒寫,視頻會無限渲染,最終搞嘎機器;
第二版:指定gif顯示時間段
錯誤寫法
我這裏寫的時候以爲shortest
參數跟shortest
互斥的,這樣寫:
#錯誤寫法
ffmpeg -i input.mp4 -stream_loop 1 -i 1.gif -filter_complex "[0:v][1:v] overlay=10:10:enable='between(t,3,4)'" output1.mp4 -y
參數釋義:
-stream_loop 1
: 這裏指定了gif播放的次數(這裏指定1次,實際播放兩次,暫搞不明白,可能跟gif的循環次數設置有關);
enable='between(t,3,4)'
表示這個動畫只有在視頻的第3秒到第4秒之間纔會顯示。
運行結果: 發現gif位置正確,顯示時間正確,就是不會動了,花了不少時間找原因;
最後排查到gif不動原因是:
1、gif是從視頻一開始加載就播放的,並不是到(t,3,4)再播放,between控制的是顯示時間;
2、這裏指定播放次數1(但實際播放兩次),耗時1.24*2=2.48s,也就是2.48秒後,gif就不動了,破案;
所以正確寫法是
1、-stream_loop -1 :gif無限循環;
2、shortest=1:以視頻流的播放結束作爲輸出結束條件;再用between控制顯示時間即可;
ffmpeg -i input.mp4 -stream_loop -1 -i 1.gif -filter_complex "[0:v][1:v] overlay=10:10:enable='between(t,3,4)':shortest=1" output1.mp4 -y
運行結果:完美!收工
總結
有時候很簡單的東西,不熟還是要踩坑;