ffmpeg で Apple HTTP Live Streaming(HLS)を扱う


ffmpeg で Apple HTTP Live Streaming(通称、HLS)形式に出力する方法。各セグメントの動画ファイルは .ts でプレイリストとなるマニフェストは .m3u8 で出力される。また segment muxer のオプションを使うことでより詳細な設定ができる。

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

公式ドキュメント:draft-pantos-http-live-streaming – HTTP Live Streaming

基本コマンド

ffmpeg -i input output.m3u8

.mp4 を HLS 形式にコーデックコピーする例
ffmpeg -i input.mp4 -bsf:v h264_mp4toannexb -c copy output.m3u8

.mp4 から暗号化とセグメントの時間指定(60秒)をする例(file.keyinfo は後述)
ffmpeg -i input.mp4 -c:v libx264 -c:a aac -hls_key_info_file file.keyinfo -hls_list_size 0 -hls_time 60 output.m3u8

一般的な配信用の HLS 出力コマンド例
ffmpeg -i input -vcodec libx264 -acodec aac -flags +loop-global_header -bsf:v h264_mp4toannexb -f segment -segment_format mpegts -segment_time 10 -segment_list output.m3u8 output_%04d.ts
公式ドキュメント:FFmpeg Formats Documentation : hls

オプション

  • hls_init_time[float]
    最初のセグメントファイルの動画時間。0 だと最初のキーフレームが来たら分割する。挙動は hls_time と同じ
    既定値:0
  • hls_time [float]
    各セグメントファイルの動画時間。指定した時間が来たら次のキーフレームで分割される
    範囲:0 から FLT_MAX まで
    既定値:2
  • hls_list_size [int]
    マニフェストに記載されるセグメント数。0 はすべて
    範囲:0 から INT_MAX まで
    既定値:5
  • hls_ts_options [string]
  • hls_vtt_options [string]
  • hls_subtitle_path [string]
    字幕ファイルのパス指定
    既定値:なし
  • hls_wrap [int]
    セグメント数の上限を指定する。上限に達すると最初のセグメントから上書きするので容量の削減になる
    範囲:0 から INT_MAX まで
    既定値:0
  • start_number [int64]
    セグメントの開始番号。開始番号を変更するのであり、映像の開始をずらすのではない
    範囲:0 から I64_MAX まで
    既定値:0
  • hls_allow_cache [int]
    キャッシュを許可するかどうかを明示的に指定する
    1 は許可する、0 は許可しない
    範囲:-1, 0, 1
    既定値:-1
  • hls_base_url [string]
    各セグメントに URL をつける。各セグメントに絶対パスを指定するときに使う
    既定値:なし
  • hls_segment_filename [string]
    hls_flags single_file を使っていないときに、各セグメントのファイル名を指定する。マニフェスト出力の前に指定する。指定しなければマニフェストファイル名に連番が振られる。Windows 環境では drawtext の時と同じように %s が使えず、組み合わせによってもエラーになる
    Windows の ffmpeg で生放送する方法 : drawtext(テキスト描写)
    例:file%03d.ts(file000.ts, file001.ts, file002.ts, …)
    既定値:なし
  • use_localtime[boolean]
    セグメントのファイル名に strftime を割り当てる。hls_segment_filenameuse_localtime_mkdir で使う
    例:-use_localtime 1 -hls_segment_filename %Y%m%d.ts(20160420.ts)
    既定値:0
  • use_localtime_mkdir[boolean]
    セグメントの末端のディレクトリ指定に strftime を割り当てる。hls_segment_filename を併用する。ディレクトリがなければつくる
    例:-use_localtime 1 -use_localtime_mkdir 1 -hls_segment_filename “%Y%m%d/%Y%m%d.ts”(20160420/20160420.ts)
    既定値:0
  • hls_key_info_file [string]
    セグメントの暗号化で使うファイルを指定する。key には 16バイトのバイナリを、IV には 16進数の文字列を指定する。書式は後述
    既定値:なし
  • hls_flags[flags]
    • single_file
      1つだけのセグメントで出力
    • delete_segments
      マニフェストに記載されていないセグメントを順番に削除していく。hls_list_size 0 を併用すると効果が無い
    • round_durations
      マニフェストに記載されている1秒未満の時間を四捨五入する
    • discont_start
      マニフェストに #EXT-X-DISCONTINUITY を最初につける。セグメントが不連続してるフラグ。配信が止まったとき仕切り直すときにつける
    • omit_endlist
      マニフェストの末端に追記される #EXT-X-ENDLIST を省略する
    • split_by_time
      時間指定で分割するのでキーフレーム以外で分割されることもある。特定のプレイヤーで挙動がよくなるかもしれないが一般的にはよくならない。hls_time と併用する
    • append_list
      マニフェストの末端に記載されている #EXT-X-ENDLISTを削除し、新しいセグメントを追記し再び最後に #EXT-X-ENDLIST を追加する
    • program_date_time
      #EXT-X-PROGRAM-DATE-TIME タグを追加する
  • hls_playlist_type[int]
    • event
      マニフェストに #EXT-X-PLAYLIST-TYPE:EVENT をつけ、hls_list_size 0 も強制される
    • vod
      マニフェストに #EXT-X-PLAYLIST-TYPE:VOD をつけ、hls_list_size 0 も強制される
  • method[string]
    指定した HTTP メソッドでセグメントファイルを作る。これを使うには HTTP サーバがそのメソッドに対応していなければならない

    例:HTTP PUT メソッドでセグメントファイルをアップロードし、refresh 時間毎に m3u8 ファイルが同じメソッドで更新される
    ffmpeg -re -i in.ts -f hls -method PUT http://example.com/live/out.m3u8

hls_key_info_file の書式

書式

key URI
key file path
IV (optional)

http://server/file.key
/path/to/file.key
0123456789ABCDEF0123456789ABCDEF

file.key を openssl で作って暗号化するシェルスクリプト

#!/bin/sh
BASE_URL=${1:-'.'}
openssl rand 16 > file.key
echo $BASE_URL/file.key > file.keyinfo
echo file.key >> file.keyinfo
echo $(openssl rand -hex 16) >> file.keyinfo
ffmpeg -f lavfi -i testsrc -t 10 -c:v h264 -vf format=yuv420p -hls_key_info_file file.keyinfo output.m3u8

上のシェルスクリプトで作られる file.keyinfo の例

./file.key
file.key
ab160b11e8ec73708cfa8797d729c378

openssl で復号する例
openssl aes-128-cbc -d -in input.ts -out output.ts -K A4856CAC48F1E48D16688FEDE9925265 -iv 0123456789ABCDEF0123456789ABCDEF

追記
オプションが追加されていたので追加した。2016年7月30日
オプションが追加されていたので追加し文章を直した。2016年9月6日
オプションが追加されていたので追加した。2016年9月11日

コメントを残す

メールアドレスが公開されることはありません。