ffmpeg 4.3から使えるフィルタ。映像の切り替えにフェード、スライド、ワイプ、ディゾルブなどのトランジションを追加するxfade
フィルタの使い方。1入力目の映像の最後につなげるフィルタではなく、1入力目の指定時間から指定時間秒トランジションを行い2入力目のファイルの先頭に切り替える。2つのファイルのタイムベースは一致しなければならないので、エラーが出るときはエラーが出たファイルにsettb
フィルタを当てる。
基本コマンド
映像をxfade
フィルタでクロスフェードし、音声もクロスフェードするにはafade、asetpts、amix
フィルタを併用する。xfade
フィルタのoffsetとafade
フィルタのstを同じ値にし、xfade
フィルタのdurationとafade
フィルタのdを同じ値にすると映像のフェードと音声のフェードが同じように変化する。
ffmpeg -i input1 -i input2 -filter_complex [0:v][1:v]xfade=transition=fade:duration=1:offset=2[v];[0:a]afade=t=out:st=2:d=1,asetpts=PTS-STARTPTS[0a];[1:a]afade=t=in:st=2:d=1,asetpts=PTS-STARTPTS[1a];[0a][1a]amix[a] -pix_fmt yuv420p -map [v] -map [a] output
1入力目のファイルのタイムベースが1/25で2入力目が異なるときに2入力目を1/25に変更する。
ffmpeg -i input1 -i input2 -filter_complex "[1:v]settb=1/25,[0:v]xfade=offset=1" -pix_fmt yuv420p output
2入力目の映像の開始時間を5秒遅らせる。このままだと音声が遅れないので無効にしている。音声は別コマンドで5秒カットして別ファイルから合わせるか、atrim、asetpts
フィルタで同じように遅らせる。
ffmpeg -i input1 -i input2 -filter_complex "[1:v]trim=5,setpts=PTS+5/TB,[0:v]xfade=offset=1" -pix_fmt yuv420p -an output
exprの例。単純なフェード。
ffmpeg -i input1 -i input2 -filter_complex xfade=expr='A*P+B*(1-P)’ -pix_fmt yuv420p -an output
http://www.ffmpeg-archive.org/xfade-filter-custom-expressions-td4694110.html:FFmpeg-users – xfade filter – custom expressions
タイムベースを揃えるにはsettb=AVTB
を使う。
video – timebase error while giving effect using FFMPEG – Super User
オプション
2つの映像は同じ解像度、フレームレート、タイムベースでなければならない。タイムベース変更はsettb
フィルタを使う。下のサンプル動画を参照。
- transition[int]
トランジションの指定 - -1, custom
- 0, fade:既定値
- 1, wipeleft
- 2, wiperight
- 3, wipeup
- 4, wipedown
- 5, slideleft
- 6, slideright
- 7, slideup
- 8, slidedown
- 9, circlecrop
- 10, rectcrop
- 11, distance
- 12, fadeblack
- 13, fadewhite
- 14, radial
- 15, smoothleft
- 16, smoothright
- 17, smoothup
- 18, smoothdown
- 19, circleopen
- 20, circleclose
- 21, vertopen
- 22, vertclose
- 23, horzopen
- 24, horzclose
- 25, dissolve
- 26, pixelize
- 27, diagtl
- 28, diagtr
- 29, diagbl
- 30, diagbr
- 31, hlslice
- 32, hrslice
- 33, vuslice
- 34, vdslice
- 35, hblur
- 36, fadegrays
- 37, wipetl
- 38, wipetr
- 39, wipebl
- 40, wipebr
- 41, squeezeh
- 42, squeezev
- 43, zoomin
- 44, fadefast
- 45, fadeslow
- 46, hlwind
- 47, hrwind
- 48, vuwind
- 49, vdwind
- duration[duration]
トランジション効果が継続する秒指定
既定値:1 - offset[duration]
トランジションが開始する秒指定
既定値:0 - expr[string]
評価式の指定。オプションは後述。扱い方が難しい
expr のオプション
geq
フィルタを参考にするがよくわからない。
- X, Y
入力映像の横と縦の解像度で 0 からはじまりW, Hまでを返す - W, H
入力映像の横と縦の解像度。固定値 - P
Progress of transition effect. - PLANE
Currently processed plane. - A
Return value of first input at current location and plane. - B
Return value of second input at current location and plane. - a0(x, y), a1(x, y), a2(x, y), a3(x, y)
Return the value of the pixel at location (x,y) of the first/second/third/fourth component of first input. - b0(x, y), b1(x, y), b2(x, y), b3(x, y)
Return the value of the pixel at location (x,y) of the first/second/third/fourth component of second input.
公式ドキュメント:FFmpeg Filters Documentation : xfade
トランジションのサンプル
公式wikiにサンプルGIFを掲載しているのでそれを引用する。
以下はフレーム数が異なるので別ファイル扱いにしている。
応用例
transition=radialを指定してプログレスバーを指定秒で回転させる。1入力目の解像度が1280×720の例。
ffmpeg -i input.mp4 -loop 1 -i circle.png -filter_complex "[0]crop=w=100:h=100:x=(1280-100)/2:y=(720-100)/2,split=2[bg1][bg2];[bg1][1]overlay=format=auto:eof_action=pass[ovr];[bg2][ovr]xfade=transition=radial:offset=0:duration=5[fg];[0][fg]overlay=(W-w)/2:(H-h)/2:format=auto:eof_action=pass:shortest=1,format=yuv420p[v]" -map "[v]" -map 0:a? -c:a copy -t 5 output.mp4
補足説明。
[0]crop=w=100:h=100:x=(1280-100)/2:y=(720-100)/2, // w、hを2入力目の解像度に揃えて、x、yは最後のoverlayの座標と揃える split=2[bg1][bg2]; // ストリームを複製する [bg1][1]overlay=format=auto:eof_action=pass[ovr]; // プログレスバーの背景に1入力を追加する [bg2][ovr]xfade=transition=radial:offset=0:duration=5[fg]; // 0秒から5秒のトランジションを追加する [0][fg]overlay=(W-w)/2:(H-h)/2:format=auto:eof_action=pass:shortest=1, // トランジションを1入力の上にオーバーレイする format=yuv420p[v] // 動画出力用のピクセルフォーマットに変換する