FFmpegでの動画の結合について以前書いた。
今回は、一度切り離したTS動画を再度連結することにトライした。
異なる場面をつなぎ合わせる編集とは違い、再連結は多くの場合PフレームやBフレーム→Iフレームという結合を要求されるため、フレーム単位での正確な操作を行わなければならない。さもなくば、同じ場面が繰り返し表示されたり画像の乱れが生じたりフレームが欠けたりする。切り出した動画の両端はIフレームになっていることを思い出してほしい。
[追記 2020/03/21] 多少正確ではありませんでした。現時点での完全版を書きました。
そんなわけで、さまざまなツールでフレームを確認しながら作業を進めた。多くの人にはいらないが、作業録として残しておく。
方法
結論から言うと極めて単純である。
file 'path/to/00001.m2ts'
outpoint 73558.878144
file 'path/to/00002.m2ts'
inpoint 73558.878144
# Comment line
のようなテキストファイル(list.txtとする)を作成し、
ffmpeg -f concat -i list.txt -map 0 -c copy cat.m2ts
を実行するだけである。
重要なのは(そして以前紹介した方法と違うのは)、outpoint
とinpoint
で同じIフレームのタイムスタンプを指定するということだ。こうすると、outpoint
タイムスタンプに達する前に00001.m2tsから脱し(つまりoutpoint
以降の00001.m2tsは入力されない)、同時に00002.m2tsがinpoint
以降から入力されるため、正確につながる。
「inpoint
やoutpoint
にIフレーム以外を指定」「重複がなくなるようにinpoint
のみ指定」「重複がなくなるようにoutpoint
のみ指定」いずれもダメであった。
なお、list.txtのfile
以外のシンタックスはすべてその前のfile
に掛かる。-map 0
は入力#0のストリームすべてを出力するためにつけてある。
参考:https://www.ffmpeg.org/ffmpeg-formats.html#concat-1
処理結果の確認
フレームの様子は以下のようにして確認した。
ffprobe -show_frames -select_streams 0 -show_entries frame=pict_type,pkt_pts_time:side_data= -of csv=p=0 cat.m2ts | grep , >cat.type
出力結果
1.882300,I
1.915667,B
1.949033,B
1.982400,P
...
詳しくはこちら。
2つのファイルを目diff。
paste 00001.type cat.type >hoge
出力結果
55564.635211,I^I1.882300,I
55564.668578,B^I1.915667,B
55564.701944,B^I1.949033,B
55564.735311,P^I1.982400,P
...
注:「^I
」はタブ文字
GOP毎にまとめる。
awk -F, 'ORS=""; $2=="I"{printf "\n%14f,%s",$1,$2} $2!="I"{print $2}' cat.type | grep , >cat.gop
出力結果
1.882300,IBBPBBPBBPBBPBB
2.382800,IBBPBBPBBPBB
2.816567,IBBPBBPBBPBBPBB
3.317067,IBBPBBPBBPBB
...
変な(「IBB」「PBB」の連続でない)GOPの抽出(あまり役に立たなかった)。
grep -C 1 -v -E ',([^B]BB)+$' cat.gop >cat.sng
出力結果
...
774.587567,IBBPBBPBBPBB
775.021333,IBBPBBPBBPBBP
775.455100,IBBPBBPBBPBB
--
--
812.959233,IBBPBBPBBPBB
813.393000,IBBPBBPBBPBBP
813.826767,IBBPBBPBBPBB
--
--
845.691933,IBBPBBPBBPBBPBB
846.192433,IBBPBBPBPBBPBBP
846.692933,IBPBB
846.859767,IBBPBBPBBPBBPBB
--
--
868.080967,IBBPBBPBBPBBPBB
868.581467,IPBPBBPBB
868.881767,IBBPBBPBBPBBPBB
...
最後に、Avidemux。動画を目で確認するのも有効である。