MP4Box は使わずに ffmpeg だけで MPEG-DASH の MPDファイルを作る方法。また ffmpeg 3.4 からは libxml2 をリンクすることで MPDファイルを読み込むこともできる。

関連記事
ffmpeg で Apple HTTP Live Streaming(HLS)を扱う

公式のガイドライン : Guidelines | DASH Industry Forum

外部記事
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

公式ドキュメント: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
  • -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.js で実装されている。ただし公式には実装されていないので実験向け。#EXT-X-PREFETCH タグが追加される。仕様書の削除を確認(2019年3月7日)。Appleの仕様書:Protocol Extension for Low-Latency HLS (Preliminary Specification) | Apple Developer Documentation
    既定値:0
  • -master_m3u8_publish_rate[int]
    指定した数のセグメント間隔毎にHLSのマスタープレイリストを繰り返し更新する
    範囲:0 から UINT32_MAX まで
    既定値:0

再生確認

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 – wikiwebm 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"

コメントを残す

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

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