Skip to content

MPEG-DASH完全ガイド:プロトコル原理、Dash.js実装とHLS比較

HLSの次に最も重要なストリーミングプロトコルがMPEG-DASHです。YouTube、Netflixが使用し、ISO国際標準です。HLSと比較して、DASHはより柔軟でオープンですが、エコシステムはHLSほど成熟していません。このガイドでは、DASHの原理から実装までをカバーします。

DASHの基本

DASH(Dynamic Adaptive Streaming over HTTP)はMPEGが2012年にリリースしたストリーミング標準です:

  • HTTPベース:標準HTTPサーバーで配信、特別なサーバー不要
  • アダプティブビットレート(ABR):ネットワーク状況に応じて品質を自動切り替え
  • オープン標準:ISO/IEC 23009-1、ロイヤリティフリー
  • コーデック非依存:H.264、H.265、VP9、AV1などをサポート

DASHの動作原理

  1. コンテンツ準備:ビデオを複数の品質レベルにエンコード
  2. セグメント分割:各品質を2-10秒のセグメントに分割
  3. MPD生成:メディアプレゼンテーション記述(MPD)ファイルを作成
  4. クライアント再生:プレーヤーがMPDを読み込み、ネットワーク状況に応じてセグメントを順次ダウンロード

HLSとの構造比較

特徴HLSDASH
標準化団体AppleMPEG (ISO)
インデックスファイルM3U8(テキスト)MPD(XML)
セグメント形式TS、fMP4fMP4、TS
ブラウザネイティブサポートSafariなし
JSライブラリhls.jsdash.js
レイテンシ5-30秒5-30秒
低遅延サポートLL-HLSLL-DASH
DRMFairPlay、Widevine、PlayReadyWidevine、PlayReady
主要ユーザーApple、TwitchYouTube、Netflix

MPDファイル構造

MPD(Media Presentation Description)はDASHのマニフェストファイル、XML形式:

xml
<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" 
     type="static"
     mediaPresentationDuration="PT1H30M0S"
     minBufferTime="PT2.0S"
     profiles="urn:mpeg:dash:profile:isoff-live:2011">
  
  <Period>
    <!-- ビデオ適応セット -->
    <AdaptationSet mimeType="video/mp4" contentType="video">
      <!-- 720p -->
      <Representation id="v1" bandwidth="2000000" width="1280" height="720" codecs="avc1.4d401f">
        <BaseURL>video_720p/</BaseURL>
        <SegmentList duration="2">
          <SegmentURL media="segment-1.m4s"/>
          <SegmentURL media="segment-2.m4s"/>
          <!-- ... -->
        </SegmentList>
      </Representation>
      <!-- 1080p -->
      <Representation id="v2" bandwidth="4000000" width="1920" height="1080" codecs="avc1.4d4028">
        <BaseURL>video_1080p/</BaseURL>
        <SegmentList duration="2">
          <SegmentURL media="segment-1.m4s"/>
          <SegmentURL media="segment-2.m4s"/>
        </SegmentList>
      </Representation>
    </AdaptationSet>
    
    <!-- オーディオ適応セット -->
    <AdaptationSet mimeType="audio/mp4" contentType="audio">
      <Representation id="a1" bandwidth="128000" codecs="mp4a.40.2">
        <BaseURL>audio/</BaseURL>
        <SegmentList duration="2">
          <SegmentURL media="segment-1.m4s"/>
          <SegmentURL media="segment-2.m4s"/>
        </SegmentList>
      </Representation>
    </AdaptationSet>
  </Period>
</MPD>

主要な要素

  • MPD:ルート要素、メディア全体の情報
  • Period:期間、異なるコンテンツセグメントを表現
  • AdaptationSet:適応セット、ビデオまたはオーディオ
  • Representation:特定の品質レベル
  • SegmentList/SegmentTemplate:セグメントのリストまたはテンプレート

Dash.jsブラウザ実装

基本的な再生

html
<!DOCTYPE html>
<html>
<head>
  <script src="https://cdn.dashjs.org/latest/dash.all.min.js"></script>
</head>
<body>
  <video controls style="width: 640px; height: 360px;"></video>
  <script>
    const video = document.querySelector('video');
    const player = dashjs.MediaPlayer().create();
    player.initialize(video, 'https://example.com/stream.mpd', true);
  </script>
</body>
</html>

高度な設定

javascript
const player = dashjs.MediaPlayer().create();

// 設定
player.updateSettings({
  streaming: {
    buffer: {
      bufferTarget: 30,        // ターゲットバッファ(秒)
      bufferTimeAtTopQuality: 30,
      bufferTimeAtTopQualityLongForm: 60
    },
    abr: {
      autoSwitchBitrate: true, // 自動ビットレート切り替え
      initialBitrate: { video: 2000000 }, // 初期ビットレート
      maxBitrate: { video: 5000000 }      // 最大ビットレート
    }
  }
});

player.initialize(video, 'stream.mpd', true);

// イベントリスナー
player.on(dashjs.MediaPlayer.events.STREAM_INITIALIZED, () => {
  console.log('ストリーム初期化完了');
});

player.on(dashjs.MediaPlayer.events.QUALITY_CHANGE_REQUESTED, (e) => {
  console.log(`品質切り替え: ${e.oldQuality} → ${e.newQuality}`);
});

品質の手動切り替え

javascript
// 利用可能な品質を取得
const bitrates = player.getBitrateInfoListFor('video');
console.log('利用可能な品質:', bitrates);

// 特定の品質に設定
player.setRepresentationForTypeByIndex('video', 0, true); // 最高品質
player.setRepresentationForTypeByIndex('video', bitrates.length - 1, true); // 最低品質

FFmpegでのDASHセグメント生成

基本的なDASH生成

bash
# 単一品質のDASHセグメント生成
ffmpeg -i input.mp4 \
  -c:v libx264 -preset fast -crf 23 \
  -c:a aac -b:a 128k \
  -f dash \
  -seg_duration 2 \
  -adaptation_sets "id=0,streams=v id=1,streams=a" \
  output.mpd

複数品質のDASH生成

bash
# 複数品質レベルを生成
ffmpeg -i input.mp4 \
  -filter_complex "[0:v]split=3[v1][v2][v3]; \
   [v1]scale=640:360[v1out]; \
   [v2]scale=1280:720[v2out]; \
   [v3]scale=1920:1080[v3out]" \
  -map "[v1out]" -c:v:0 libx264 -b:v:0 800k \
  -map "[v2out]" -c:v:1 libx264 -b:v:1 2000k \
  -map "[v3out]" -c:v:2 libx264 -b:v:2 4000k \
  -map a:0 -c:a:0 aac -b:a:0 128k \
  -map a:0 -c:a:1 aac -b:a:1 128k \
  -map a:0 -c:a:2 aac -b:a:2 128k \
  -f dash \
  -seg_duration 2 \
  -adaptation_sets "id=0,streams=v:0,v:1,v:2 id=1,streams=a:0,a:1,a:2" \
  output.mpd

DASH vs HLS:どちらを選ぶべきか

DASHを選ぶ場合

  • Androidとウェブが主なターゲット
  • YouTubeやNetflixのような大規模ストリーミング
  • 低遅延ストリーミングが必要(LL-DASH)
  • オープン標準とコーデック柔軟性を重視

HLSを選ぶ場合

  • iOSユーザーが多い
  • Safariネイティブサポートが必要
  • 成熟したエコシステムが必要
  • Twitchのようなライブストリーミングプラットフォーム

CMAFで両方をサポート

CMAF(Common Media Application Format)はHLSとDASHの両方で使用できる共通フォーマットです:

bash
# CMAFセグメントを生成
ffmpeg -i input.mp4 \
  -c:v libx264 -c:a aac \
  -f dash \
  -seg_duration 2 \
  -use_template 1 \
  -use_timeline 1 \
  -format_options "movflags=cmaf" \
  output.mpd

同じセグメントをHLSとDASHの両方で使用でき、ストレージと帯域幅を節約できます。

よくある問題

問題原因解決策
Safariで再生できないDASHネイティブ非サポートHLSまたはdash.js使用
品質切り替えが頻繁ABR設定が適切でないバッファターゲットを増やす
セグメントダウンロード失敗CORS問題サーバーにCORSヘッダー追加
レイテンシが高い通常のDASHLL-DASH使用
MPD解析エラーXMLフォーマットエラーMPDファイルを検証

まとめ

MPEG-DASHはHLSに次ぐ重要なストリーミングプロトコルです:

  • オープン標準:ISO国際標準、ロイヤリティフリー
  • 柔軟性:コーデック非依存、DRM柔軟
  • 大規模ユーザー:YouTube、Netflixが採用
  • 低遅延:LL-DASHでサブ秒遅延可能

クイックリファレンス:

  • 基本再生: dash.js + player.initialize(video, 'stream.mpd', true)
  • FFmpeg生成: ffmpeg -i input.mp4 -c:v libx264 -c:a aac -f dash output.mpd
  • 複数品質: filter_complexで複数スケール生成
  • iOSサポート: HLSまたはCMAF使用

参考文献

最終更新: