51

まったく同じ長さの 2 つのビデオがあり、ffmpeg を使用してそれらを 1 つのビデオ ファイルにスタックしたいと考えています。

これどうやってするの?

4

3 に答える 3

209

vstack (垂直)、hstack (水平)、またはxstack (カスタム レイアウト) フィルターを使用します。他の方法よりも簡単で高速です。

2 つのビデオまたは画像を結合/スタックする

垂直

vstackフィルターの使用。

ここに画像の説明を入力

ffmpeg -i input0 -i input1 -filter_complex vstack=inputs=2 output

ビデオは同じ幅でなければなりません。

水平

hstackフィルターの使用。

ここに画像の説明を入力

ffmpeg -i input0 -i input1 -filter_complex hstack=inputs=2 output

動画は同じ高さでなければなりません。

縁取りあり

パッドフィルターを使用。この例では、2 つの辺の間に 5 ピクセルの黒い境界線を作成します。

ここに画像の説明を入力

ffmpeg -i input0 -i input1 -filter_complex "[0]pad=iw+5:color=black[left];[left][1]hstack=inputs=2" output

オーディオ付き

ダウンミックスして元のチャンネル配置を使用する

ここに画像の説明を入力

amerge フィルターを追加して、両方の入力からのオーディオ チャネルを結合します。

ffmpeg -i input0 -i input1 -filter_complex "[0:v][1:v]vstack=inputs=2[v];[0:a][1:a]amerge=inputs=2[a]" -map "[v]" -map "[a]" -ac 2 output
  • これは、各入力にステレオ オーディオ ストリームが含まれていることを前提としています。

  • -ac 2両方の入力にマルチチャンネル オーディオが含まれている場合に、ステレオにダウンミックスするために含まれています。たとえば、両方の入力がステレオの場合、 を省略すると、ステレオではなく 4 チャンネルの出力オーディオ ストリームが得られます-ac 2

各入力からのすべてのオーディオを別々のチャンネルに入れる

ここに画像の説明を入力

amerge (またはamix ) およびpanフィルターを使用します

ffmpeg -i input0 -i input1 -filter_complex "[0:v][1:v]vstack=inputs=2[v];[0:a][1:a]amerge=inputs=2,pan=stereo|c0<c0+c1|c1<c2+c3[a]" -map "[v]" -map "[a]"  output
  • これは、各入力にステレオ オーディオ ストリームが含まれていることを前提としています。

1 つの特定の入力からオーディオを使用する

この例では、次のオーディオを使用しますinput1

ffmpeg -i input0 -i input1 -filter_complex "[0:v][1:v]vstack=inputs=2[v]" -map "[v]" -map 1:a output

サイレント オーディオの追加 / 1 つの入力にオーディオがない場合

オーディオを含む入力とオーディオを含まない入力を混在させると、各入力がオーディオを必要とするため、マージは失敗します。これを防ぐには、 anullsrc フィルターを使用してサイレント オーディオを追加します。

ffmpeg -i input0 -i input1 -filter_complex "[0:v][1:v]vstack=inputs=2[v];anullsrc[silent];[0:a][silent]amerge=inputs=2[a]" -map "[v]" -map "[a]" -ac 2 output.mp4

3 動画または画像

ここに画像の説明を入力

ffmpeg -i input0 -i input1 -i input2 -filter_complex "[0:v][1:v][2:v]hstack=inputs=3[v]" -map "[v]" output

垂直にしたい場合は、hstack の代わりに vstack を使用してください。


2x2 グリッド

ここに画像の説明を入力

xstack の使用

ffmpeg -i input0 -i input1 -i input2 -i input3 -filter_complex "[0:v][1:v][2:v][3:v]xstack=inputs=4:layout=0_0|w0_0|0_h0|w0_h0[v]" -map "[v]" output

hstackvstackの使用

ffmpeg -i input0 -i input1 -i input2 -i input3 -filter_complex "[0:v][1:v]hstack=inputs=2[top];[2:v][3:v]hstack=inputs=2[bottom];[top][bottom]vstack=inputs=2[v]" -map "[v]" output

この構文は理解しやすいですが、上記の xstack を使用するよりも効率的ではありません。


テキスト付きの 2x2 グリッド

ここに画像の説明を入力

drawtextフィルターの使用:

ffmpeg -i input0 -i input1 -i input2 -i input3 -filter_complex
"[0]drawtext=text='vid0':fontsize=20:x=(w-text_w)/2:y=(h-text_h)/2[v0];
 [1]drawtext=text='vid1':fontsize=20:x=(w-text_w)/2:y=(h-text_h)/2[v1];
 [2]drawtext=text='vid2':fontsize=20:x=(w-text_w)/2:y=(h-text_h)/2[v2];
 [3]drawtext=text='vid3':fontsize=20:x=(w-text_w)/2:y=(h-text_h)/2[v3];
 [v0][v1][v2][v3]xstack=inputs=4:layout=0_0|w0_0|0_h0|w0_h0[v]"
-map "[v]" output

4x4

xstack フィルターを使用します。合計 16 本のビデオの例:

ffmpeg -i input0 -i input1 -i input2 -i input3 -i input4 -i input5 -i input6 -i input7 -i input8 -i input9 -i input10 -i input11 -i input12 -i input13 -i input14 -i input15 -i input16 -filter_complex "[0:v][1:v][2:v][3:v][4:v][5:v][6:v][7:v][8:v][9:v][10:v][11:v][12:v][13:v][14:v][15:v]xstack=inputs=16:layout=0_0|w0_0|w0+w1_0|w0+w1+w2_0|0_h0|w4_h0|w4+w5_h0|w4+w5+w6_h0|0_h0+h4|w8_h0+h4|w8+w9_h0+h4|w8+w9+w10_h0+h4|0_h0+h4+h8|w12_h0+h4+h8|w12+w13_h0+h4+h8|w12+w13+w14_h0+h4+h8" output.mp4

最初に入力をスケーリングする必要がある場合:

ffmpeg -i input0 -i input1 -i input2 -i input3 -i input4 -i input5 -i input6 -i input7 -i input8 -i input9 -i input10 -i input11 -i input12 -i input13 -i input14 -i input15 -i input16 -filter_complex "[0:v]scale=iw/4:-1[v0];[1:v]scale=iw/4:-1[v1];[2:v]scale=iw/4:-1[v2];[3:v]scale=iw/4:-1[v3];[4:v]scale=iw/4:-1[v4];[5:v]scale=iw/4:-1[v5];[6:v]scale=iw/4:-1[v6];[7:v]scale=iw/4:-1[v7];[8:v]scale=iw/4:-1[v8];[9:v]scale=iw/4:-1[v9];[10:v]scale=iw/4:-1[v10];[11:v]scale=iw/4:-1[v11];[12:v]scale=iw/4:-1[v12];[13:v]scale=iw/4:-1[v13];[14:v]scale=iw/4:-1[v14];[15:v]scale=iw/4:-1[v15];[v0][v1][v2][v3][v4][v5][v6][v7][v8][v9][v10][v11][v12][v13][v14][v15]xstack=inputs=16:layout=0_0|w0_0|w0+w1_0|w0+w1+w2_0|0_h0|w4_h0|w4+w5_h0|w4+w5+w6_h0|0_h0+h4|w8_h0+h4|w8+w9_h0+h4|w8+w9+w10_h0+h4|0_h0+h4+h8|w12_h0+h4+h8|w12+w13_h0+h4+h8|w12+w13+w14_h0+h4+h8" output.mp4

入力のサイズ変更/スケーリング

vstack の場合は両方のビデオが同じで、hstack の場合は同じ高さである必要があるため、他のビデオの 1 つを他のビデオと一致するようにスケーリングする必要がある場合があります。

input0 の幅を 640 に設定し、縦横比を維持しながら高さを自動的に設定する単純なスケールフィルターの例:

ffmpeg -i input0 -i input2 -filter_complex "[0:v]scale=640:-1[v0];[v0][1:v]vstack=inputs=2" output

動画の遅延/一時停止

この例では、左上のビデオを再生し、他のビデオを一時停止します。左上のビデオが終了すると、右上のビデオが再生されます。

tpadadelayxstack、およびamixフィルターを使用します。

ffmpeg -i top-left.mp4 -i top-right.mp4 -i bottom-left.mp4 -i bottom-right.mp4 -filter_complex "[1]tpad=start_mode=clone:start_duration=5[tr];[2]tpad=start_mode=clone:start_duration=10[bl];[3]tpad=start_mode=clone:start_duration=15[br];[0][tr][bl][br]xstack=inputs=4:layout=0_0|w0_0|0_h0|w0_h0[v];[1:a]adelay=5s:all=true[a1];[2:a]adelay=10s:all=true[a2];[3:a]adelay=15s:all=true[a3];[0:a][a1][a2][a3]amix=inputs=4[a]" -map "[v]" -map "[a]" output.mp4
  • この例では、各入力の持続時間が 5 秒であると想定しています。必要に応じて値を調整start_durationadelayます。

  • このコマンドには、FFmpeg 4.3 以降が必要です。

  • xstack の複雑さが気に入らない場合は、例 4: 2x2 gridに示すように、代わりにいくつかの hstack/vstack を使用できます。

于 2015-11-17T18:59:51.413 に答える
29

これを行う新しい、より簡単な方法については、この質問に対するこの回答を参照してください。


古いバージョン: FFmpeg のpadmovie、およびoverlayフィルター
を使用してこれを行うことができるはずです。コマンドは次のようになります。

ffmpeg -i top.mov -vf 'pad=iw:2*ih [top]; movie=bottom.mov [bottom]; \
  [top][bottom] overlay=0:main_h/2' stacked.mov

最初に、一番上にあるはずのムービーが、その高さの 2 倍になるまでパディングされます。すると下のムービーが読み込まれます。次に、パディングされたムービーの高さの半分のオフセットで、パディングされたトップ ムービーにボトム ムービーがオーバーレイされます。

于 2012-07-19T02:32:44.507 に答える