【ffmpeg】動画・音声を連結する concat の使い方 其の3

前回記事は無劣化で連結する方法を紹介したがコンテナフォーマットが限られていた。今回紹介する方法は同じ解像度や fps など同じエンコード形式、音声は同じサンプリング数ならば多くのコンテナフォーマットで連結ができる。

【ffmpeg】動画・音声を連結する concat の使い方 其の2

追記 2016年4月3日
Unsafe file name というエラーが出るので safe オプションを足した。-safe 0 は絶対パスで input.txt の内容を記述したときにつける。
FFmpeg Formats Documentation :: concat < Syntax < Options
[FFmpeg-user] FFMeg Concat giving "unsafe file name" error on new server install
FFmpeg-users - protocol CONCAT has broken In last versions

基本コマンド
ffmpeg -f concat -safe 0 -i input.txt -c copy output.mp4

このコマンドは入力ファイルをテキスト形式で読み込んでそれを上から順番に連結する方法である。

input.txt の内容。シングルクォート(')でファイルパスを挟む
file 'E:/video/test1.mp4'
file 'E:/video/test2.mp4'
# ffmpeg -f concat -safe 0 -i input.txt -c copy output.mp4
# test1.mp4, test2.mp4 の順番に連結

# 行は実行されないコメント扱いになる。
ファイル名だけでなく絶対パス指定するときは -safe 0 をつける。
パス指定は相対パス、絶対パスが使える。
パス指定の注意点はバックスラッシュ(\)ではなく スラッシュ(/)を指定することだったが、どちらでも使える。(2019年10月時点)

この方法が前回記事の -i concat: 形式よりも優れているのは入力ファイル形式に制限がおそらくないと言うこと。.mp4 や .flv をそのまま連結でき、連結しながらもコンテナ変換もできる。たとえば、H.264/AAC の FLV 動画を MP4 動画として出力することもできる。

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

input.txt の内容(絶対パス)
file 'E:/video/test1.flv'
file 'E:/video/test2.flv'


input.txt の内容(相対パス)
file test1.flv
file test2.flv


リストにあるストリームに字幕があるときは map 0:s:0、データなら map 0:d:0 をつける。

ffmpeg -f concat -safe 0 -i input.txt -c copy -map 0:v:0 -map 0:a:0 -map 0:d:0 output.ts

Preserve id3 tag with ffmpeg concat and copy multiple transport streams - Stack Overflow

ネット上のソースを入力するときはエスケープする。

input.txt の内容
file http:\/\/192.168.0.87:8090
duration 00:00:02.00
file http:\/\/192.168.0.158:8090
duration 00:00:02.00


raspberry pi - Switching between 2 streams after a set amount of time in ffmpeg - Super User

「Non-monotonous DTS in output stream 」でDTSのエラーが出るときはファイルのフレームレートとtbnを調べて出力オプションの-r-video_track_timescale で揃える。

ffmpeg -i 2997.mp4 -r 30 -video_track_timescale 1000k -c:a copy 30.mp4

codec - ffmpeg concat failing with dts timing error - Stack Overflow

キーフレームをinpoint、outpointで指定すると過不足なく任意の区間をコピーできる。キーフレームの場所はffprobeを使って調べる。
ffprobe -v error -i input -select_streams v:0 -skip_frame nokey -show_entries frame=pkt_pts_time -of csv=print_section=0

ffprobe の使い方

input.txt の内容

file 'input.mp4'
outpoint 60
file 'input.mp4'
inpoint 120
outpoint 240
file 'input.mp4'
inpoint 300



コマンドの利用例
N を使わない新しいニコ生用の rtmpdump と ffmpeg(librtmp)

画像ファイルを取り込む場合のフレームレート指定は別途フィルタ内で指定する。
ffmpeg -f concat -safe 0 -i input.txt -vf "settb=AVTB,setpts=N/30/TB,fps=30" output.mp4

Ffmpeg, concat input.txt, set frame rate? - Super User

手動の関連記事


FFmpeg Formats Documentation :: concat
Concatenate – FFmpeg
ニコ生のTSを無劣化で連結する Andy's FLV Joiner
関連記事

コメント

st

大変参考になりました。HLSのaac断片ファイルをffmpegで結合する
ために使いました。2000個を超えることもあるので、3番目が絶対で
す。aacの無変換の結合ソフトは殆どありません。猛スピードで結合
され、2000個がわずか30秒くらいです。参考のバッチは---

断片のファイルを、専用の別フォルダに移して名前の昇順としますが、
このフォルダに次のバッチファイルをNotePadなどにコピーして、
aac-ffmpeg-join.batなどとして保存し、さらにffmpeg.exeをコピーして
置いて下さい。

if exist output.aac del output.aac
if exist list.txt del list.txt
dir *.aac /b /a-d > list.txt
if exist dst.txt del dst.txt
for /f "delims=" %%l in (list.txt) do @echo file^ %%l >> dst.txt
ffmpeg -f concat -safe 0 -i dst.txt -c copy output.aac

ここでこのバッチファイルaac-ffmpeg-join.batをダブルクリックで起動
します。これで結合が行われ、output.aacとして作成されます。
約2000個のファイルを約30秒程度で結合します。結合が終了したら、すべての
xxxxx.aacを削除して、次のデータに備えます。できたoutput.aacは移動
した方がよいでしょう。存在していると、次回に削除されます。

-

他サイトではMP4でも下記のような形で結合できるように書いてあったが、自分がやったらエラーが出ました。

ffmpeg -i "concat:1.mp4|2.mp4|3.mp4" -c copy dst.mp4
エラー
[mov,mp4,m4a,3gp,3g2,mj2 @ 0000000000492400] Found duplicated MOOV Atom. Skipped it
※このエラーメッセージについては海外の人も質問してるのをいくつか見つけました。

MP4だから?と思い、仰るファイルリスト読み込み方式でやってみたら、見事にMP4の無劣化結合できました。非常に助かった!

やらかし

連結方法(動画を繋げる)方法は色々あるのですが、結合方法(Video、audio、subtitleを一つにする)が書かてれいるサイトが殆どない状態です

-safe 0 concatの記載などは見つけたのですが、それだとsafe 0が分からんとエラー…
特にalacを使用したい場合が上手くいかず困っております(alacもffmpegを使用しエンコードした物を使用)

お力添えいただけると幸いです

ロベルト

Re: タイトルなし
映像と音声、字幕を合わせる方法について追記したのでこちらを参照ください。
【ffmpeg】 マルチトラックの動画の作り方
https://looooooooop.blog.fc2.com/blog-entry-960.html

文系の口曲がり阿呆太郎

ダブルクオーテーションでなくシングルクオート
素晴らしい記事です。
他のとこで似たようなコマンドが書かれていましたが、微妙に違い、ま、コンピューターでは微妙な違いでどうにもならないので、助かりました。
自分のケースでは、ビデオのファイル名の場所をダブルクオーテーションでなくシングルクオートで囲むことと-safeで解決しました。
ちなみにLinuxです。
ありがとうございます。
非公開コメント

プロフィール

ロベルト

お問い合わせはこちらまで
robelt2525[at]gmail.com

中の人 @nico_lab

広告リンク
Amazon
楽天市場

ブログ更新用 @blo_nico_lab

詳しいプロフィールはこちら

当ブログは、Amazonアソシエイトに参加しています。