segmentmuxer とは時間やフレーム数指定でストリームを分割する。出力ファイル名にはimage2muxer と同じように連番出力(%d)や、-strftimeオプションを使って日時設定もできる。正確にストリームを分割するにはキーフレームを分割毎の先頭に挿入しなければならない。キーフレームが先頭に来ないとキーフレームが来るまで映像が乱れる原因になる。hlsmuxer のオプションと併用することで詳細に分割設定ができる。

-reset_timestamps 1を付けると2分割以降のファイルの PTS がリセットされて動画投稿サイト向けに分割したファイルの投稿が可能になる。

ffmpeg で Apple HTTP Live Streaming(HLS)を扱う
ffmpeg で指定秒ごとに分割する方法

フィルタ内で分割するなら。
詳細な分割設定ができる Segment

基本コマンド

300秒毎にMP4に分割出力する。-flags +global_headerをつけると一部プレイヤーでの再生互換が高まる。
ffmpeg -i input.mp4 -map 0 -c copy -flags +global_header -f segment -segment_time 300 -segment_format_options movflags=+faststart -reset_timestamps 1 out-%02d.mp4

-segment_time 60で60秒ごとにMP4で分割し-segment_list out.csvで分割データを記載したファイルも出力する。
ffmpeg -i input.mp4 -map 0 -c copy -flags +global_header -f segment -segment_time 60 -segment_list out.csv -segment_format_options movflags=+faststart -reset_timestamps 1 out%03d.mp4

-segment_list out.ffconcatで分割したファイルをまとめたリストを出力する。
ffmpeg -i input.mp4 -map 0 -c copy -flags +global_header -f segment -segment_time 60 -segment_list out.ffconcat -segment_format_options movflags=+faststart -reset_timestamps 1 out%03d.mp4

上のout.ffconcatを読み込んで1つのファイルに戻す。
ffmpeg -i out.ffconcat -c copy -segment_format_options movflags=+faststart output.mp4

-segment_timesで1032, 11414, 11847 の秒時間になったら分割する。つまり4分割される。-reset_timestampsを有効にすると分割ファイル毎の PTS が0秒開始になる。
ffmpeg -i input.mp4 -map 0 -c copy -flags +global_header -f segment -segment_times 1032,11414,11847 -segment_format_options movflags=+faststart -reset_timestamps 1 out-%02d.mp4

-segment_wrap 100で常に最新の100フレームの画像を出力し、それ以外を削除する。
ffmpeg -i input -q:v 3 -f segment -segment_format mjpeg -segment_wrap 100 -segment_time 0.001 out%d.jpg

再エンコードして常にセグメントを固定秒にするにはキーフレーム間隔を強制する。-sc_threshold 0でシーンチェンジによるキーフレーム挿入を0にして、5秒間隔で分割するには-gのkeyintと-force_key_framesでキーフレーム間隔を固定させている。映像は30fpsとして5秒間の150フレームを-gで指定している。
ffmpeg -i input -c:v libx264 -crf 23 -c:a aac -map 0 -segment_time 5 -g 150 -sc_threshold 0 -force_key_frames "expr:gte(t,n_forced*5)" -f segment output%03d.ts

-force_key_framesは2重引用符で挟むのと、カンマの後をバックスラッシュでエスケープしない。これらはエラーになる。

-force_key_frames 'expr:gte(n,n_forced*60)'
-force_key_frames "expr:gte(n\,n_forced*60)"
-force_key_frames expr:gte(n\,n_forced*60)

秒時間でキーフレームを指定しセグメントを分割して、キーフレーム時間を丸める。
ffmpeg -i input.mp4 -force_key_frames 1,2,3,5,8,13,21 -map 0 -c:v libx264 -c:a aac -flags +global_header -f segment -segment_time 60 -segment_times 1,2,3,5,8,13,21 -segment_time_delta 0.05 -segment_format_options movflags=+faststart -reset_timestamps 1 out%03d.mp4

そのほかにカンマ区切りのhh:mm:ss.ms指定ができる。-force_key_frames 00:02:11.000,00:01:11.000

-segment_timeであらかじめ大きな値を指定していれば、1ファイルでも strftime書式が使える。使えるフォーマットは、ffmpeg で Apple HTTP Live Streaming(HLS)を扱う | セグメントファイル名の設定を参照。
ffmpeg -i input -map 0 -c c:v libx264 -c:a aac -f segment -segment_time 99999 -strftime 1 "output-%Y%m%d.ts"

ffmpeg Documentation : force_key_frames
linux – Slicing video file into several segments – Super User

最初のフレームから分割できないときは入力ファイルの前に-ignore_editlist 1をつける
ffmpeg -ignore_editlist 1 -i input.mp4 以下略

The video track has an edit list specifying a truncated track

公式ドキュメント:FFmpeg Formats Documentation : segment, stream_segment, ssegment

オプション

ヘルプコマンド ffmpeg -h muxer=segment

  • -reference_stream [string]
    どのストリームを参照するか
    既定値:”auto”
  • -segment_format [string]
    セグメントのコンテナフォーマット指定。コンテナフォーマットと異なる場合、例えば Motion JPEG は-segment_format mjpegの出力拡張子はjpgを指定する
    既定値:出力コンテナフォーマットと同じ
  • -segment_format_options [string]
    フォーマットオプションの指定。MP4出力のときには-segment_format_options movflags=+faststart、TS出力のときには-segment_format_options mpegts_flags=+initial_discontinuityが使える。FFmpeg Formats Documentation : mov, mp4, ismvFFmpeg Formats Documentation : mpegtsを参照
  • -segment_list [string]
    セグメントリスト名の指定。.m3u8 ならHLSプレイリストに、.txt ならセグメントだけのリストに、.ffconcat ならリストファイルに、.csv ならセグメント名と開始時間、終了時間のリストに、.xml はDASHプレイリストにはならない
    既定値:無指定
  • -segment_header_filename [string]
    ヘッダに1つのファイルを書き込む
  • -segment_list_flags [flags]
    • cache:キャッシュを許可。M3U8 リストだけに反映。既定値
    • live:HLS 配信に有効
  • -segment_list_size [int]
    リストに記載されるセグメント数。0 はすべて
    範囲:0 – INT_MAX
  • -segment_list_type [int]
  • セグメントリストのファイル形式。-segment_listの拡張子で自動設定する

    • -1, flat:普通のテキスト形式。既定値
    • 0, csv
    • 1, ext
    • 2, ffconcat
    • 3, m3u8
    • 4, hls
  • -segment_atclocktime [boolean]
    1 で 00:00 開始の時計の時間通りに分割する。-segment_clocktime_offsetで分割開始時間を遅延させる
    既定値:0
  • -segment_clocktime_offset [duration]
    -segment_atclocktimeを有効にしたときに分割時間を遅延させる。例えば-segment_time 900 -segment_clocktime_offset 300を併用すると900秒毎に分割するが、一度N時5分に強制分割するので5分になる前の分割時間が-segment_timeになるようにエンコード開始時に分割調整する
    既定値:0
  • -segment_clocktime_wrap_duration [duration]
    set segment clocktime wrapping duration
    既定値:INT64_MAX
  • -segment_time [string]
    各セグメントの秒指定。キーフレームでないと指定した時間通りに分割しない。Apple の推奨値は 10。映像のキーフレーム間隔を元に設定する
    既定値:2
  • -segment_time_delta [duration]
    各セグメントの開始時間を決める時間(PTS)を特定する
    既定値:0
  • -min_seg_duration[duration]
    各セグメントの最小時間の指定。-segment_timeを指定してGOPサイズが可変のときに使える。-segment_timeと同じ値にすると概ね指定時間より長い時間で分割される。厳格に指定時間で分割するにはシーンチェンジ分割を無効にする
    既定値:0(無効)
  • -segment_times [string]
    ,で区切って分割時間を指定する。3分より長いストリームを用いて60,120,180を指定すると、60秒、60秒、60秒、残り時間全部で分割する
    既定値:0
  • -segment_frames [string]
    ,で区切って分割フレーム数を指定する。-segment_timesと同様に分割タイミングが来たときにキーフレームが来ていなければ次のキーフレームで分割する
    既定値:0
  • -segment_wrap [int]
    セグメント数の上限を指定する。上限に達すると最初のセグメントから上書きするので容量の削減になる
    範囲:0 から INT_MAX まで
    既定値:0
  • -segment_list_entry_prefix [string]
    リストの各セグメントに URL を付与する。各セグメントに絶対パスを指定するときに使う
    既定値:なし
  • -segment_start_number [int]
    セグメントの開始番号。開始番号を変更するのであり、映像の開始をずらすのではない
    範囲:0 から I64_MAX まで
    既定値:0
  • -segment_wrap_number [int]
    set the number of wrap before the first segment
    範囲:0 から I64_MAX まで
    既定値:0
  • -strftime [boolean]
    各セグメント名にstrftimeを使う。1にしたときは必ずセグメント名にstrftimeの書式(%Y%m%d%H%M%Sなど)を用いなければならない。ffmpeg で Apple HTTP Live Streaming(HLS)を扱う | セグメントファイル名の設定を参照。
    既定値:0
  • -increment_tc [boolean]
    各セグメント間のタイムコードを増やす
    既定値:0
  • -break_non_keyframes [boolean]
    1にしたときにセグメントの開始にキーフレーム以外も含める。特定のプレイヤーで挙動がよくなるかもしれないが一般的にはよくならない
    既定値:0
  • -individual_header_trailer [boolean]
    各セグメントにヘッダ、トレイラを書き込む
    既定値:1
  • -write_header_trailer [boolean]
    セグメントの冒頭にヘッダを、末尾にトレイラを書き込む
    既定値:1
  • -reset_timestamps [boolean]
    タイムスタンプをリセットして各セグメントのタイムスタンプが 0 になる。HLS など分割を前提に読み込む以外はリセットした方が分割後のファイルが扱いやすい。ただし一部のコーデックやフォーマットでは使えない
    既定値:0
  • -initial_offset [duration]
    タイムスタンプのオフセット秒指定
    既定値:0
  • -write_empty_segments [boolean]
    各セグメントで空データが出力された場合にそのまま出力するか
    既定値:0

追記
オプションと順番の並び替え。2017年2月12日
画像出力のコマンド例。2018年5月24日
再エンコードでセグメント間隔とキーフレーム間隔指定の例。2019年8月3日
オプションの説明を一部詳しくした。2019年8月19日
-segment_list の説明を詳しくした。2019年10月30日
-segment_clocktime_offset の説明を詳しくした。2022年6月3日

コメントを残す

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

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