ffmpeg 4.5から使える予定のフィルタ。いままではselect、aselectフィルタで複数の区間をフィルタ内で分割できたのがより直感的に分割できるようになった。タイムライン編集が使えないフィルタを使ったり、エンコードパラメータを複数使い分けて1つのファイルに戻すなどに使う。

特定の映像フレームや音声サンプルを出力するselect, aselect

Tがあればタイムライン編集に対応している。
ffmpeg -filters : gist.github.com

基本コマンド

最初から90秒まで、90秒から180秒まで、180秒から最後まで分割出力する。setpts、asetptsフィルタを使いPTSをリセットする。
ffmpeg -i input -filter_complex "segment=90|180[0v][1v][2v];[1v]setpts=PTS-STARTPTS[1v];[2v]setpts=PTS-STARTPTS[2v];asegment=90|180[0a][1a][2a];[1a]asetpts=PTS-STARTPTS[1a];[2a]asetpts=PTS-STARTPTS[2a]" -map [0v] -map [0a] output1.mp4 -map [1v] -map [1a] output2.mp4 -map [2v] -map [2a] output3.mp4

タイムライン編集が使えないaddroiフィルタを使い、区間ごとに品質を変更する。
ffmpeg -i input -filter_complex "segment=90|180[0v][1v][2v];[1v]addroi=0:0:iw:ih:-2/51,setpts=PTS-STARTPTS[1v];[2v]addroi=0:0:iw:ih:2/51,setpts=PTS-STARTPTS[2v];[0v][1v][2v]concat=n=3:v=1:a=0" -c:v libx264 -crf 23 -c:a copy output.mp4

秒指定ではなくhh:mm:ss形式はシングルクォートで挟みエスケープする。
ffmpeg -i input -filter_complex "segment='00\:01\:00|00\:01\:30'[0v][1v][2v];[1v]addroi=0:0:iw:ih:-2/51,setpts=PTS-STARTPTS[1v];[2v]addroi=0:0:iw:ih:2/51,setpts=PTS-STARTPTS[2v];[0v][1v][2v]concat=n=3:v=1:a=0" -c:v libx264 -crf 23 -c:a copy output.mp4

concatフィルタで連結せずに分割のままエンコードパラメータを変更してx264のstitchableを有効にしてエンコードし、改めて1つのファイルにconcatする方法もある。この場合はsegmentmuxerで分割しても同じことができる。2番目以降のエンコードパラメータ部分のあるmdatをbsfフィルタで消すことでバイナリを少し小さくできる。音声を分割出力すると後で連結したときに分割部分が瞬間的に途切れることがあるのでconcatで連結して出力する。

詳細な分割設定ができる Segment

ffmpeg -i input -filter_complex "segment=90|180[0v][1v][2v];[1v]setpts=PTS-STARTPTS[1v];[2v]setpts=PTS-STARTPTS[2v];asegment=90|180[0a][1a][2a];[1a]asetpts=PTS-STARTPTS[1a];[2a]asetpts=PTS-STARTPTS[2a];[0a][1a][2a]concat=n=3:v=0:a=1[a]" -map [0v] -crf 23 -x264-params stitchable=1 output1.mp4 -map [1v] -crf 20 -x264-params stitchable=1 -bsf:v filter_units=remove_types=6 output2.mp4 -map [2v] -crf 27 -x264-params stitchable=1 -bsf:v filter_units=remove_types=6 output3.mp4 -map [a] audio.m4a

concat.txt
file output1.mp4
file output2.mp4
file output3.mp4

分割部分が一定間隔でないとfpsがおかしくなることがあるのでsettsビットストリームフィルタで修正する。
ffmpeg -f concat -safe 0 -i concat.txt -i audio.m4a -bsf:v setts=dts=N/((24000/1001)*TB):pts=PTS+N/((24000/1001)*TB)-DTS -c copy output.mp4

特定フレーム間に別のエンコードパラメータを使い分ける方法にx264のzonesがある。
ffmpeg_libx264.md : gist.github.com

concatフィルタの代わりにinterleaveフィルタで連結する方法もある。こちらはPTSリセットが不要なのと、出力オプションに元の映像のフレームレート-rを指定しないと正常なフレームで出力できない。
ffmpeg -i input -filter_complex "segment=90|180,interleave=3" -r 30000/1001 output
ffmpeg -i input -filter_complex "segment=90|180,interleave=3;asegment=90|180,ainterleave=3" -r 30000/1001 output

複数の映像を1つの映像に合わせるinterleave

公式ドキュメント:FFmpeg Filters Documentation : segment, asegment

オプション

|毎に分割する時間を指定し、指定数プラス1が出力数になる。時間指定のほかに映像はフレーム指定、音声はサンプル指定ができる。各数値の接頭辞に+をつけると前の分割位置からの相対位置指定になる。

  • timestamps[string]
    時間指定。秒指定と、hh:mm:ss指定ができる。hh:mm:ss形式はシングルクォートで挟みエスケープする
  • frames[string]
    フレーム指定。segmentフィルタで使える
  • samples[string]
    サンプル指定。asegmentフィルタで使える

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)