⚠️ 実行前に確認してください(音や映像が欠けたファイルができても、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の確認コマンドをもう一度実行してください。
関連記事
- xfade フィルタでクロスフェード・トランジション効果を追加する
- 動画をトリミング・カット(trim/ss/to)する
- 動画を結合・連結する
よくある質問
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 フィルタを使うほうが安全です。