MP4Boxは使わずにffmpegだけでMPEG-DASHのMPDファイルを作る方法。またffmpeg 3.4からはlibxml2をリンクすることでMPDファイルを読み込むこともできる。各セグメントの.m4sファイルは最初に読み込むinit.mp4を毎回参照し各セグメントの.m4sファイルをデコードしている。
関連記事
ffmpeg で Apple HTTP Live Streaming(HLS)を扱う
公式のガイドライン : DASH-IF Live Media Ingest Protocol : web.archive
外部記事
- MPEG DASHを知る – Qiita
- AbemaTV の MPEG-DASH 対応 – Qiita
- HLS と MPEG-DASH でメディアを共通化してみる – Qiita
- RTMP to MPEG-DASH でライブストリーミングを行うやり方 – Qiita
基本コマンド
すべてのセグメントをMPDに記載してコピーする。
ffmpeg -i input.mp4 -c copy -window_size 0 -movflags +faststart output.mpd
1つの映像に1つ目はオリジナルをコピーし、2つめはアスペクト比固定で横解像度は2で割れて、縦解像度360pにリサイズして2つのストリームをリアルタイム-reで出力する。-mapを2度使うことで2出力にしている。
ffmpeg -re -i input.mp4 -map 0:v:0 -map 0:a:0 -map 0:v:0 -map 0:a:0 -c:v:0 copy -c:a:0 copy -filter:v:1 "scale=-2:360" -c:v:1 libx264 -profile:v:1 main -b:v:1 600k -c:a:1 aac -b:a:1 128k -f dash -window_size 5 -adaptation_sets "id=0,streams=v id=1,streams=a" -movflags +faststart output.mpd
改行しわかりやすくしたもの。
ffmpeg -re -i input.mp4 -map 0 -map 0 -c:v:0 copy -c:a:0 copy -filter:v:1 "scale=-2:360" -c:v:1 libx264 -profile:v:1 main -b:v:1 600k -c:a:1 aac -b:a:1 128k -f dash -window_size 5 -adaptation_sets "id=0,streams=v id=1,streams=a" -movflags +faststart output.mpd
公式ドキュメントには-movflagsを以下に利用している。
-movflags empty_moov+separate_moof+default_base_moof+cmaf
ffmpeg Documentation : mov, mp4, ismv
その他のフラグは以下に利用している。
-fflags genpts -export_side_data prft
ffmpeg Documentation : Format Options
ffmpeg Documentation : Codec Options
公式ドキュメント:FFmpeg Formats Documentation : dash(Muxers)
オプション
ffmpeg -h muxer=dash
- -adaptation_sets[string]
セグメント毎にどのデータを納めるか。streamsに 0 から始まる整数を入れるとチャンネルマップに記載されたデータが納まる。vなら映像のすべて、aなら音声のすべてが納まる。映像と音声は別idで納める
例:”id=0,streams=0,1,2 id=1,streams=3,4″
例:”id=0,streams=v id=1,streams=a” - -window_size[int]
マニフェストに記載されるセグメント数。0 はすべて
範囲:0 から INT_MAX まで
既定値:0 - -extra_window_size[int]
マニフェストに記載されなかったセグメントをどれだけ削除せずに残すか
範囲:0 から INT_MAX まで
既定値:5 - -min_seg_duration[int]
セグメントの最小時間(マイクロ秒)。廃止予定なので次の-seg_durationを使う
範囲:0 から INT_MAX まで。5000000 で5秒
既定値:5e+006(5000000) - -seg_duration[duration]
セグメントの最小秒時間。-use_template 1 -use_timeline 0にするとセグメントの平均秒時間になり、それ以外はセグメントの最小秒時間になる
既定値:5 - -remove_at_exit[boolean]
エンコードが終わったらすべてのセグメントを削除する
既定値:0 - -use_template[boolean]
Enable (1) or disable (0) use of SegmentTemplate instead of SegmentList.
既定値:1 - -use_timeline[boolean]
Enable (1) or disable (0) use of SegmentTimeline in SegmentTemplate.
既定値:1 - -single_file[boolean]
セグメントではなく1つのファイルで出力する
既定値:0 - -single_file_name[string]
DASH-templated name to be used for baseURL. Implies storing all segments in one file, accessed using byte ranges - -init_seg_name[string]
イニシャルファイルのファイル名の指定
既定値:init-stream$RepresentationID$.m4s
ファイル名は init-stream0.m4s のようになる - -media_seg_name[string]
セグメントファイルのファイル名の指定
既定値:chunk-stream$RepresentationID$-$Number%05d$.m4s
ファイル名は chunk-stream0-00001.m4s のようになる - -utc_timing_url[string]
ISO 規格の UTC タイムスタンプを UTCTiming schemeIdUri に記入する。無記入だと指定されない
例:https://time.akamai.com/?iso - -method[string]
指定した HTTP メソッドでセグメントを作る。これを使うには HTTP サーバがそのメソッドに対応していなければならない。PUT, POST が使える
既定値:PUT - -http_user_agent[string]
HTTP ヘッダの User-Agent フィールドを優先させる
既定値:なし - -http_persistent[boolean]
HTTP 接続を継続する
既定値:0 - -hls_playlist[boolean]
fragmented MP4のMPDファイル作成と同時に VERSION:7 の HLS用のマスターマニフェスト(master.m3u8)、各ストリームのマニフェスト(media_%d.m3u8)を同時に出力する
既定値:0 - -hls_master_name[string]
マスタープレイリストのファイル名の指定
既定値:master.m3u8 - -streaming[boolean]
ライブ配信モードの指定。指定すると各フレームが moof(Movie Fragment)になる
既定値:0 - -timeout[duration]
I/O ソケット処理のタイムアウトの指定
既定値:-0.000001 - -index_correction[boolean]
セグメントインデックスが正しいかどうかを調べる
既定値:0 - -format_options[string]
- -global_sidx[boolean]
global SIDX atom を書き込む。mp4 の1ファイル出力で-streaming 0ときに使える
既定値:0 - -dash_segment_type[int]
セグメントのファイルタイプの指定 - 0, auto。既定値
- 1, mp4
- 2, webm
- -ignore_io_errors[boolean]
開いたり書き込んだりするときの IO エラーを無視する。長時間のネットワーク越しの配信に効果的
既定値:0 - -lhls[boolean]
Low-latency HLS(LHLS、低遅延HLS)を有効化する。hls.jsで実装されている。#EXT-X-PREFETCHタグが追加される。Appleの仕様書:Protocol Extension for Low-Latency HLS (Preliminary Specification) | Apple Developer Documentation
既定値:0 - -master_m3u8_publish_rate[int]
指定した数のセグメント間隔毎にHLSのマスタープレイリストを繰り返し更新する
範囲:0 から UINT32_MAX まで
既定値:0 - -write_prft[boolean]
producer reference time elementを書き込む
既定値:auto - -mpd_profile[flags]
mpdプロファイルの指定 - dash。既定値
- dvb_dash
- -http_opts[dictionary]
httpのプロトコルオプション - -target_latency[duration]
低遅延dashのときの遅延時間の指定
既定値:0 - -min_playback_rate[rational]
再生時の求める最小レート
範囲:0.5から1.5まで
既定値:1/1 - -max_playback_rate[rational]
再生時の求める最大レート
範囲:0.5から1.5まで
既定値:1/1
再生確認
Dash-Industry-Forum/dash.jsを使うことで手軽にブラウザで再生確認ができる。
libxml2を有効にした ffplay ならそのまま MPDファイルを読み込める。
ffplay -i output.mpd
<!DOCTYPE html> <html> <head> <script src="https://cdn.dashjs.org/latest/dash.all.min.js"></script> <title>MPEG DASH TEST</title> <style> video { width: 640px; height: 360px; } </style> </head> <body> <div> <video data-dashjs-player autoplay src="output.mpd" controls></video> </div> </body> </html>
Adaptive Bitrate Streaming
VP9の Adaptive Bitrate(ABR)Streaming のコマンド例。複数の解像度とビットレートにエンコードする。dash 1設定についてはInstructions to playback Adaptive WebM using DASH – wiki、webm dash encoding… What are the correct ffmpeg parameters? – Stack Overflowを参照。
ffmpeg -i input -vf scale=-2:90:force_original_aspect_ratio=decrease -c:v libvpx-vp9 -b:v 250k -keyint_min 150 -g 150 -threads 1 -an -f webm -dash 1 video_90p_250k.webm
ffmpeg -i input -vf scale=-2:180:force_original_aspect_ratio=decrease -c:v libvpx-vp9 -b:v 500k -keyint_min 150 -g 150 -threads 1 -an -f webm -dash 1 video_180p_500k.webm
ffmpeg -i input -vf scale=-2:360:force_original_aspect_ratio=decrease -c:v libvpx-vp9 -b:v 750k -keyint_min 150 -g 150 -threads 2 -an -f webm -dash 1 video_360p_750k.webm
ffmpeg -i input -vf scale=-2:360:force_original_aspect_ratio=decrease -c:v libvpx-vp9 -b:v 1000k -keyint_min 150 -g 150 -threads 2 -an -f webm -dash 1 video_360p_1000k.webm
ffmpeg -i input -vf scale=-2:720:force_original_aspect_ratio=decrease -c:v libvpx-vp9 -b:v 1500k -keyint_min 150 -g 150 -threads 3 -an -f webm -dash 1 video_720p_1500k.webm
音声が1つの場合は一度だけエンコードする。
ffmpeg -i input -vn -c:a libopus -b:a 128k -f webm -dash 1 audio_128k.webm
エンコードされたファイルをまとめて MPD ファイルを作る。
ffmpeg -f webm_dash_manifest -i video_90p_250k.webm -f webm_dash_manifest -i video_180p_500k.webm -f webm_dash_manifest -i video_360p_750k.webm -f webm_dash_manifest -i video_360p_1000k.webm -f webm_dash_manifest -i video_720p_1500k.webm -f webm_dash_manifest -i audio_128k.webm -c copy -map 0 -map 1 -map 2 -map 3 -map 4 -map 5 -f webm_dash_manifest -adaptation_sets "id=0,streams=0,1,2,3,4 id=1,streams=5" output.mpd
出力数だけ-mapを指定し個別設定する。キーフレーム間隔は動画のフレームレートの4倍としている。
ffmpeg -re -i input.mp4 -c:v libvpx-vp9 -c:a libopus -b:a 128k -filter:v:0 scale=1280:-2 -filter:v:1 scale=640:-2 -filter:v:2 scale=480:-2 -b:v:0 1000k -minrate 500k -maxrate 1500k -threads 3 -b:v:1 300k -minrate 150k -maxrate 400k -threads 2 -b:v:2 200k -minrate 100k -maxrate 300k -threads 1 -quality realtime -speed 4 -keyint_min 120 -g 120 -map 0 -map 0 -map 0 -f dash -seg_duration 4 -adaptation_sets "id=0,streams=v id=1,streams=a" output.mpd
読みやすく改行したもの。
ffmpeg -re -i input.mp4 -c:v libvpx-vp9 -c:a libopus -b:a 128k -filter:v:0 scale=1280:-2 -filter:v:1 scale=640:-2 -filter:v:2 scale=480:-2 -b:v:0 1000k -minrate 500k -maxrate 1500k -threads 3 -b:v:1 300k -minrate 150k -maxrate 400k -threads 2 -b:v:2 200k -minrate 100k -maxrate 300k -threads 1 -quality realtime -speed 4 -keyint_min 120 -g 120 -map 0 -map 0 -map 0 -f dash -seg_duration 4 -adaptation_sets "id=0,streams=v id=1,streams=a" output.mpd
teeを使って映像は3種類リサイズし、音声は1種類エンコードしたDASHのプレイリストを出力する例。
ffmpeg -i input -c:v libvpx-vp9 -quality realtime -speed 4 -keyint_min 120 -g 120 -filter:v:0 scale=1280:-2 -b:v:0 1000k -minrate 500k -maxrate 1500k -threads 3 -filter:v:1 scale=640:-2 -b:v:1 300k -minrate 150k -maxrate 400k -threads 2 -filter:v:2 scale=480:-2 -b:v:2 200k -minrate 100k -maxrate 300k -threads 1 -c:a libopus -b:a 128k -map 0:v -map 0:v -map 0:v -map 0:a -f tee "[f=dash:seg_duration=4]output.mpd|[select='v:0,a:0']out1.webm|[select='v:1,a:0']out2.webm|[select='v:2,a:0']out3.webm"
読みやすく改行したもの。
ffmpeg -i input -c:v libvpx-vp9 -quality realtime -speed 4 -keyint_min 120 -g 120 -filter:v:0 scale=1280:-2 -b:v:0 1000k -minrate 500k -maxrate 1500k -threads 3 -filter:v:1 scale=640:-2 -b:v:1 300k -minrate 150k -maxrate 400k -threads 2 -filter:v:2 scale=480:-2 -b:v:2 200k -minrate 100k -maxrate 300k -threads 1 -c:a libopus -b:a 128k -map 0:v -map 0:v -map 0:v -map 0:a -f tee "[f=dash:seg_duration=4]output.mpd| [select='v:0,a:0']out1.webm| [select='v:1,a:0']out2.webm| [select='v:2,a:0']out3.webm"