⚠️ 実行前に確認してください(音や映像が欠けたファイルができても、FFmpeg が正常終了することがあります)

  • リストの途中に存在しないファイル(パスの打ち間違いを含む)があると、FFmpeg はエラーを表示しますが、そこまでの部分だけのファイルを作って正常終了します。
  • コーデック・解像度・フレームレートがそろっていないと、途中で音や映像が欠けたり、タイムスタンプ(再生する時刻の情報)がずれたりします。
  • 結合したら、ffprobe で出力の長さを確かめてください。

concat デマルチプレクサとは

concat デマルチプレクサは、テキストファイルに書いたファイルの一覧を上から順に読み込み、再エンコードせずにつなげる機能です。デマルチプレクサ(demuxer)は、ファイルから映像や音声のデータを取り出す部分のことです。

コーデックや設定が同じファイル同士なら、短時間で結合できます。

基本的な使い方

ステップ1: リストファイルの事前確認(必須)

リストファイルを作る前に、結合するファイルがすべてあるか、コーデックがそろっているかを確かめます。

# ファイルの存在確認
for f in clip1.mp4 clip2.mp4 clip3.mp4; do
  if [ -f "$f" ]; then
    echo "OK: $f"
  else
    echo "MISSING: $f"
  fi
done

# 映像と音声の設定の確認(ffprobe は1回に1ファイルずつ調べる)
for f in clip1.mp4 clip2.mp4 clip3.mp4; do
  ffprobe -v error -select_streams v:0 \
    -show_entries stream=codec_name,width,height,r_frame_rate,time_base \
    -of csv=p=0 "$f"
  ffprobe -v error -select_streams a:0 \
    -show_entries stream=codec_name,sample_rate,time_base \
    -of csv=p=0 "$f"
done

ファイルごとに、映像の codec_name,width,height,r_frame_rate,time_base(コーデック名・幅・高さ・フレームレート・タイムベース)と、音声の codec_name,sample_rate,time_base(コーデック名・サンプルレート・タイムベース)が表示されます。タイムベースは、再生する時刻を数える単位です。これが全ファイルで同じで、ストリーム(映像や音声のデータ)の数と順番もそろっていれば、-c copy で結合できます。タイムベースだけが違っても、結合した動画の長さがおかしくなります。

ステップ2: リストファイル(concat.txt)を作成する

printf "file 'clip1.mp4'\nfile 'clip2.mp4'\nfile 'clip3.mp4'\n" > concat.txt

できあがる concat.txt の中身は次のとおりです。

file 'clip1.mp4'
file 'clip2.mp4'
file 'clip3.mp4'

1行に1ファイルずつ、file '...' の形で書きます。ファイルの場所(パス)はシングルクォート(’)で囲みます。

各行は必ず file で始めてください。file のつづりを間違えると、unknown keyword のエラーで止まります。余計な空白は無視されるので、問題ありません。

ステップ3: concat デマルチプレクサで結合する

ffmpeg -f concat -safe 0 -i concat.txt -c copy output.mp4

-c copy は、映像と音声のデータを再エンコードせず、そのまま写す指定です。

リストファイルの書き方

相対パスの例

file 'clip1.mp4'
file 'clip2.mp4'
file 'clip3.mp4'

絶対パスの例(Windowsの場合は通常相対パスを推奨)

file '/path/to/clip1.mp4'
file '/path/to/clip2.mp4'

特殊文字を含むファイル名

ファイル名にシングルクォート(’)が入っているときは、その部分を '\'' と書きます。

file 'it'\''s a clip.mp4'

オプション一覧

オプション 説明
-f concat concat デマルチプレクサを使う
-safe 0 絶対パス、../ のように . で始まる部分があるパス、英数字・.・_・- 以外の文字(空白や日本語など)を含むファイル名を許可する
-i concat.txt リストファイルを入力にする
-c copy 再エンコードせずにコピーする

再エンコードなし結合の前提条件

-c copy で結合するには、すべてのファイルで次の項目がそろっている必要があります。

  • 映像コーデックが同じ(例: すべて H.264)
  • 解像度が同じ(例: すべて 1920×1080)
  • フレームレートが同じ(例: すべて 30fps)
  • 音声コーデックが同じ(例: すべて AAC)
  • サンプルレートが同じ(例: すべて 44100Hz)
  • タイムベースが同じ(ステップ1で表示される time_base)
  • ストリームの数と順番が同じ(例: どれも映像が先で、音声が1本)。ffprobe clip1.mp4 を実行すると、Stream #0:0、Stream #0:1 の順に表示されます

そろっていないと、エラーで止まるか、壊れたファイルを書き出したまま正常終了します。映像と音声がずれる、トラックが1本消える、音声のデータが映像のトラックに入る、といったことが起きます。

音声付きファイルの結合

printf "file 'clip1.mp4'\nfile 'clip2.mp4'\n" > concat.txt
ffmpeg -f concat -safe 0 -i concat.txt -c copy output_with_audio.mp4

-c copy を付けると、映像も音声もそのままコピーされます。

結合後の整合性確認(重要)

結合したら、元のファイルの長さの合計と、出力の長さを比べます。

# 各入力ファイルの尺を合計
total=0
for f in clip1.mp4 clip2.mp4 clip3.mp4; do
  dur=$(ffprobe -v error -show_entries format=duration \
    -of default=noprint_wrappers=1:nokey=1 "$f")
  total=$(echo "$total + $dur" | bc)
done
echo "入力合計尺: ${total}秒"

# 出力の尺を確認
out_dur=$(ffprobe -v error -show_entries format=duration \
  -of default=noprint_wrappers=1:nokey=1 output.mp4)
echo "出力尺: ${out_dur}秒"

# 差が 0.5 秒以上あれば結合が不完全な可能性があります

concat フィルタとの違い

方式 再エンコード 速度 要件
concat デマルチプレクサ なし 速い コーデック・形式が同じであること
concat フィルタ あり 遅い コーデックが違ってもよい(解像度はそろえる)

形式の違うファイルをつなぐときは、次のように concat フィルタを使います。concat フィルタはつなぐだけで、切り替えの効果(トランジション)は入りません。効果を入れたいときは xfade(映像)と acrossfade(音声)を使います。

ffmpeg -i clip1.mp4 -i clip2.mp4 -filter_complex "[0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1[v][a]" -map "[v]" -map "[a]" output.mp4

トラブルシューティング

映像がずれる・音声がずれる場合

PTS(表示する時刻の情報)が欠けたファイルが混ざっていると、ずれることがあります。その場合は -fflags +genpts を足して、PTS を作り直してください。ファイルごとの設定の違いが原因のずれは、これでは直りません。

ffmpeg -f concat -safe 0 -fflags +genpts -i concat.txt -c copy output.mp4

“Unsafe file name” エラー

リストに絶対パスや、空白・日本語などを含むファイル名があるのに、-safe 0 を付けていないと出ます。

NG例: ffmpeg -f concat -i concat.txt -c copy output.mp4
OK:   ffmpeg -f concat -safe 0 -i concat.txt -c copy output.mp4

出力が入力より短い・途中で切れる

リストファイルのパスが間違っているか、コーデックがそろっていない可能性があります。ステップ1の確認コマンドをもう一度実行してください。

関連記事

よくある質問

concat プロトコルと concat デマルチプレクサの違いは?

プロトコル方式(concat:a.ts|b.ts)は、ファイルの中身をバイト単位でそのままつなげるだけです。使えるのは、MPEG-TS、MPEG-PS(.mpg)、DV など、ファイルをそのままつなげても読める形式に限られます。デマルチプレクサ方式(-f concat -i list.txt)は、どのコンテナでも映像や音声をいったん取り出して、新しいファイルに入れ直します(再多重化)。

concat:a.ts|b.ts はいつ使える?

放送の録画などで使われる MPEG-TS(Transport Stream)や、MPEG-PS(.mpg、DVD の .vob)、DV のように、ファイルをそのままつなげても読める形式で使えます。MP4 や MOV では使えないので、concat デマルチプレクサか concat フィルタを使ってください。

MP4 で concat プロトコルが壊れるのはなぜ?

MP4 には、ファイル全体の目次にあたる情報(moov atom)があります。そのため、バイト単位で単純につなげることはできません。代わりに -f concat -i list.txt -c copy を使ってください。

コーデックが違うファイルを concat プロトコルで繋げる?

できません。MPEG-TS でも、コーデックと設定がそろっている必要があります。違う場合は、concat フィルタを使って再エンコードします。

concat プロトコルは本番で使って大丈夫?

放送のキャプチャなど、どこで作られたかがわかっている MPEG-TS だけを扱うなら問題ありません。それ以外では、concat デマルチプレクサか concat フィルタを使うほうが安全です。