PC

ffmpegで複数の動画ファイルを結合する方法

複数のmp4ファイルを一つのmp4のファイルに統合したいときってありますよね。

例えば、同時刻に角度の異なる二つの監視カメラで撮った映像を、横に並べてみたいとかです。

今回は、ffmpegを使って複数の動画ファイルを並べる方法を紹介します。

こちらのstack overflowが参考になります。

環境

  • Windows10, WSL2, Ubuntu 20.04
  • ffmpeg version 4.2.4-1 ubuntu0.1

ffmpegのインストールとオプション

インストール

今回はWSL2のUbuntu20.04でffmpegを利用します。インストール方法は簡単で、下記のコマンドを実行するだけです。

$ sudo apt install ffmpeg

代表的なオプション

よく利用するオプションについてまとめておきます。

オプション説明
-filter_copmlex複雑なフィルタ処理を記述できるオプション
-vcodec映像コーデックの指定
-crf映像品質。低いほど高品質
-map抽出対象の指定。vは映像、aは音声を示す。大括弧[]はfilterに対する処理となる。(例:-map "[v]"は、filterされた映像という意味)
[数字]:[v,a]何番目の映像(v)か音声(a)かを表す(例:"0:v"は1番目のファイルの映像という意味)

基本的に、filter_complexオプションを変更することで、結合する方法を変更していきます。

ffmpegで動画を統合する

早速複数の結合方法を確認していきましょう。

二つの動画を横並びにつなげる

下記のように、left.mp4とright.mp4を横につなげる方法です。注意することは、left.m4とright.mp4の高さ(解像度)が同じ必要があることです。

left.mp4right.mp4

コマンドは下記です。

$ ffmpeg -i left.mp4 -i right.mp4 \
         -filter_complex "hstack" -vcodec libx264 -crf 23 output.mp4

今回、filter_copmlexはhstackのみ指定しています。予想はつくと思いますが、hstackをvstackにすると、二つの動画を上下に並べることができます(vstackの場合は2つの動画の横幅が同じ必要があります)。

3つの動画を横に並べる

下記のように、3つのファイルを並べる方法です。

left.mp4
center.mp4right.mp4
ffmpeg -i left.mp4 -i center.mp4 -i right.mp4 \
       -filter_complex "[0:v][1:v][2:v]hstack=inputs=3[v]" \
       -map "[v]" -vcodec libx264 -crf 23 output.mp4

filter_complexが少し複雑になりました。ffmpegではデフォルトで二つのファイルを結合するようになっているので、3個以上の場合はオプションを指定する必要があります。

サイズの異なる動画を並べる

上記では、動画を横に並べるときは高さが同じである必要がありました。異なるサイズの動画を並べるときはどうすればよいのでしょうか。

サイズを合わせてから結合します。下記では横に並べるほかに、縦に並べる方法も記述してあります。

left.mp4

right.mp4

# 高さを380にして、横に並べる
ffmpeg -i left.mp4 \
       -i right.mp4 \
       -filter_complex "[0:v]scale=-2:380[v0];[1:v]scale=-2:380[v1];[v0][v1]hstack=inputs=2" \
       -vcodec libx264 -crf 23 output.mp4

# 横幅を600にして、縦に並べる
ffmpeg -i top.mp4 \
       -i bottom.mp4 \
       -filter_complex "[0:v]scale=600:-2[v0];[1:v]scale=600:-2[v1];[v0][v1]vstack=inputs=2" \
       -vcodec libx264 -crf 23 output.mp4

# 条件に合わせて高さ・横幅の大きさを決定する
ffmpeg -i left.mp4 \
       -i right.mp4 \
       -filter_complex "[0:v]scale='if(gt(a,500/300),-1,500)':'if(gt(a,500/300),300,-1)',setsar=1,crop=500:300[v0];[1:v]scale='if(gt(a,500/300),-1,500)':'if(gt(a,500/300),300,-1)',setsar=1,crop=500:300[v1];[v0][v1]hstack=inputs=2" \
       -vcodec libx264 -crf 23 output.mp4

上では、scale=width:heightで画像のサイズを変更しています。-1を指定するとアスペクト比を固定してリサイズします。-2は対象が奇数の時に利用できるオプションで、変換後の解像度は繰り上げられて偶数になります。

サイズ変更の方法は他にもたくさんありますが、とりあえず代表的だと思うものを紹介しました。

グリッドに動画を並べる

下記のようにグリッドの配置方法です。

topleft.mp4

topright.mp4

bottomleft.mp4

 

ffmpeg -i topleft.mp4 \
       -i topright.mp4 \
       -i bottomleft.mp4 \
       -filter_complex "[0:v][1:v][2:v]xstack=inputs=3:layout=0_0|w0_0|0_h0[v]" \
       -map "[v]" -vcodec libx264 -crf 23 output.mp4

xstackとlayoutを利用します。想像がつくと思いますが、4つ目の動画として右下に追加したい場合は、inputs=4にして"w0_h0"を追加します。

まとめ

ffmpegを利用して複数の動画を結合す方法をまとめました。特に難しいソフトウェアは必要ないので、ffmpegを覚えると非常に便利だと思います。

  • この記事を書いた人

たかけの夫。IT系コンサルティング会社に勤務し、主にクラウドや機械学習に関するコンサルティング業務を行う三十路男。IT技術・投資に興味を持ち、家族と楽に人生を楽しみたい人。

-PC
-, , , ,