web-dev-qa-db-ja.com

ffmpegでフェードイン/アウト効果を使用して5つの画像でビデオを作成する

5つの画像を使用して、ffmpegで60秒のビデオを作成する必要があります。各画像は15秒間表示する必要があります。 15秒後、最初の画像がフェードアウトし、2番目の画像がフェードインする必要があります。その後、2番目の画像がフェードアウトし、3番目の画像がフェードインする必要があります。 ffmpegコマンドを使用してこれを実現する方法を教えてください。

32
user384847

黒にディップ/フェード

下にスクロールしてクロスフェードメソッドを表示します。

fade example

各画像が5秒間表示され、それぞれに1秒間続くフェードがある例。 各画像入力の幅、高さ、サンプルのアスペクト比は同じです。サイズが異なる場合は、以下の例#3を参照してください。

MP4出力

ffmpeg \
-loop 1 -t 5 -i input0.png \
-loop 1 -t 5 -i input1.png \
-loop 1 -t 5 -i input2.png \
-loop 1 -t 5 -i input3.png \
-loop 1 -t 5 -i input4.png \
-filter_complex \
"[0:v]fade=t=out:st=4:d=1[v0]; \
 [1:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v1]; \
 [2:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v2]; \
 [3:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v3]; \
 [4:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v4]; \
 [v0][v1][v2][v3][v4]concat=n=5:v=1:a=0,format=yuv420p[v]" -map "[v]" out.mp4

音声あり

上記と同じですが、オーディオを使用します。

ffmpeg \
-loop 1 -t 5 -i input0.png \
-loop 1 -t 5 -i input1.png \
-loop 1 -t 5 -i input2.png \
-loop 1 -t 5 -i input3.png \
-loop 1 -t 5 -i input4.png \
-i audio.m4a \
-filter_complex \
"[0:v]fade=t=out:st=4:d=1[v0]; \
 [1:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v1]; \
 [2:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v2]; \
 [3:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v3]; \
 [4:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v4]; \
 [v0][v1][v2][v3][v4]concat=n=5:v=1:a=0,format=yuv420p[v]" -map "[v]" -map 5:a -shortest out.mp4

さまざまなサイズまたは任意のサイズの入力画像の場合

最初の例と同様ですが、幅x高さが異なる入力画像を使用します。 1280x720ボックスに収まるようにパディングされます。

ffmpeg \
-loop 1 -t 5 -i input0.png \
-loop 1 -t 5 -i input1.png \
-loop 1 -t 5 -i input2.png \
-loop 1 -t 5 -i input3.png \
-loop 1 -t 5 -i input4.png \
-filter_complex \
"[0:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fade=t=out:st=4:d=1[v0]; \
 [1:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v1]; \
 [2:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v2]; \
 [3:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v3]; \
 [4:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v4]; \
 [v0][v1][v2][v3][v4]concat=n=5:v=1:a=0,format=yuv420p[v]" -map "[v]" out.mp4

パッド(レターボックス/ピラーボックス)の代わりにトリミング(画面いっぱい)する場合、またはアップスケーリングを防止する場合は、 静的なサイズのプレーヤーに合わせてビデオのサイズを変更する の例を参照してください。

GIF出力

ffmpegを使用して、妥当な品質でビデオをGIFに変換するにはどうすればよいですか?

ffmpeg \
-framerate 10 -loop 1 -t 5 -i input0.png \
-framerate 10 -loop 1 -t 5 -i input1.png \
-framerate 10 -loop 1 -t 5 -i input2.png \
-framerate 10 -loop 1 -t 5 -i input3.png \
-framerate 10 -loop 1 -t 5 -i input4.png \
-filter_complex \
"[0:v]fade=t=out:st=4:d=1[v0]; \
 [1:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v1]; \
 [2:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v2]; \
 [3:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v3]; \
 [4:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v4]; \
 [v0][v1][v2][v3][v4]concat=n=5:v=1:a=0,split[v0][v1]; \
 [v0]palettegen[p];[v1][p]paletteuse[v]" -map "[v]" out.gif

-loop出力オプションを使用して、GIFループの回数を制御します。このオプションを使用しない場合、デフォルトは無限ループです。 -1の値はループなしです。

使用されるオプションとフィルター:

  • -tは、各入力の期間を秒単位で設定します。

  • -loop 1は画像をループします。ループしないと、1フレームの期間になります。

  • -framerateは、入力画像のフレームレートを設定します(宣言されていない場合のデフォルトは25です)。 GIFの作成に役立ちます。

  • scale with pad 入力画像を特定の均一なサイズに合わせる(例#3で使用)。

  • fade フェードインおよびフェードアウトします。 dは、フェードの期間です。 stは起動時です。

  • concat 各画像を連結(または「結合」)します。

  • format MP4を出力する場合は非FFmpegベースのプレーヤーと互換性のあるクロマサブサンプリングスキームを出力し、libx264(ビルドでサポートされている場合はMP4出力のデフォルトのエンコーダー)で出力します。

  • split フィルター出力のコピーを作成します。 1つのコマンドですべてを行うには、pallet *フィルターが必要です。

  • palettegen および paletteuse 見栄えの良いGIFを作成します。


クロスフェード

crossfade example

各画像が5秒間表示され、それぞれに1秒間続くクロスフェードがある例。 各画像入力の幅、高さ、サンプルのアスペクト比は同じです。サイズが異なる場合は、上記の例3を適用してください。

MP4出力

ffmpeg \
-loop 1 -t 5 -i 1.png \
-loop 1 -t 5 -i 2.png \
-loop 1 -t 5 -i 3.png \
-loop 1 -t 5 -i 4.png \
-loop 1 -t 5 -i 5.png \
-filter_complex \
"[1]format=yuva444p,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+4/TB[f0]; \
 [2]format=yuva444p,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+8/TB[f1]; \
 [3]format=yuva444p,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+12/TB[f2]; \
 [4]format=yuva444p,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+16/TB[f3]; \
 [0][f0]overlay[bg1];[bg1][f1]overlay[bg2];[bg2][f2]overlay[bg3]; \
 [bg3][f3]overlay,format=yuv420p[v]" -map "[v]" -movflags +faststart out.mp4

音声あり

ffmpeg \
-loop 1 -t 5 -i 1.png \
-loop 1 -t 5 -i 2.png \
-loop 1 -t 5 -i 3.png \
-loop 1 -t 5 -i 4.png \
-loop 1 -t 5 -i 5.png \
-i music.mp3 \
-filter_complex \
"[1]format=yuva444p,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+4/TB[f0]; \
 [2]format=yuva444p,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+8/TB[f1]; \
 [3]format=yuva444p,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+12/TB[f2]; \
 [4]format=yuva444p,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+16/TB[f3]; \
 [0][f0]overlay[bg1];[bg1][f1]overlay[bg2];[bg2][f2]overlay[bg3]; \
 [bg3][f3]overlay,format=yuv420p[v]" -map "[v]" -map 5:a -shortest -movflags +faststart out.mp4

オーディオ付きの2つのビデオ間のクロスフェード

各入力から5秒のセグメントを選択し、1秒のクロスフェードを追加します。

ffmpeg -i input0.mp4 -i input1.mp4 -filter_complex \
"[0:v]trim=start=5:end=10,setpts=PTS-STARTPTS[v0];
 [1:v]trim=start=12:end=17,setpts=PTS-STARTPTS+4/TB,format=yuva444p,fade=st=4:d=1:t=in:alpha=1[v1];
 [v0][v1]overlay,format=yuv420p[v];
 [0:a]atrim=start=5:end=10,asetpts=PTS-STARTPTS[a0];
 [1:a]atrim=start=12:end=17,asetpts=PTS-STARTPTS[a1];
 [a0][a1]acrossfade=d=1[a]" \
-map "[v]" -map "[a]" output.mp4

GIF出力

ffmpeg \
-framerate 10 -loop 1 -t 5 -i 1.png \
-framerate 10 -loop 1 -t 5 -i 2.png \
-framerate 10 -loop 1 -t 5 -i 3.png \
-framerate 10 -loop 1 -t 5 -i 4.png \
-framerate 10 -loop 1 -t 5 -i 5.png \
-filter_complex \
"[1]format=rgba,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+4/TB[f0]; \
 [2]format=rgba,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+8/TB[f1]; \
 [3]format=rgba,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+12/TB[f2]; \
 [4]format=rgba,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+16/TB[f3]; \
 [0][f0]overlay[bg1];[bg1][f1]overlay[bg2];[bg2][f2]overlay[bg3];[bg3][f3]overlay,split[v0][v1]; \
 [v0]palettegen[p];[v1][p]paletteuse[v]" -map "[v]" out.gif

-loop出力オプションを使用して、GIFループの回数を制御します。このオプションを使用しない場合、デフォルトは無限ループです。 -1の値はループなしです。

54
llogan

画像のフォルダーへのパスを取り込み、ffmpegでクロスフェードビデオを出力する一般的なbashスクリプトを作成しました。

https://Gist.github.com/anguyen8/d0630b6aef6c1cd79b9a1341e88a573e

スクリプトは基本的にフォルダー内の画像を見て、上記の@LordNeckbeardによる回答と同様のコマンドを出力し、コマンドを実行します。このスクリプトは、フォルダーに多くの画像があり、手間のかかる長いコマンドを手動で入力したくない場合に役立ちます。

4
anh_ng8