Wowza Streaming Engine での MPEG-DASH ストリーミング

## はじめに

この記事では、Wowza Streaming Engine での MPEG-DASH 方式でのストリーミングに関する
技術的に詳細な設定・カスタマイズの方法について触れます。

## MPEG-DASH MPD マニフェストについて

MPEG-DASH サーバーは、メディア プレゼンテーション記述 (MPD) マニフェスト ファイルで、
利用可能なメディア セグメント URL のリストをプレーヤーに提供します。
その後、プレイヤーは、中断のない再生を行うために、必要に応じてメディア セグメントを順次要求します。

MPD ファイル内でこのセグメント URL のリストの識別方法を定義する方式をセグメントアドレス方式とは呼び、
以下のセグメントアドレス方式があります。

* セグメント リスト方式
  * 利用可能なすべてのセグメントについて、セグメント URL の完全なリストを提供する方式です
* セグメント テンプレート (時刻ベース) 方式
  * プレイヤーがセグメント URL リストを作成できるようにするための URL テンプレートを提供する方式です
  * セグメント URL にはセグメントごとの開始時刻が含まれます
* セグメント テンプレート (セグメント番号ベース) 方式
  * プレイヤーがセグメント URL リストを作成できるようにするための URL テンプレートを提供する方式です
  * セグメント URL にはセグメントごとのセグメントの番号 (インデックス番号など) が含まます
* セグメント ベース (BaseURL) 方式
  * すべてのセグメントが単一の URL (BaseURL) で識別されるセグメント分割を行わない方式で、セグメントがバイトレンジの HTTP リクエストを通じて取得する方式です

Wowza Streaming Engine の MPEG-DASH サポートでは、セグメントベース方式以外のセグメントアドレス方式の MPD 形式をサポートしていて、
プレイヤーは以下の URL フォーマット指定で必要なマニフェスト形式を指定できます。

http://[アドレスまたはホスト名]:[ポート]/[アプリケーション名]/[アプリインスタンス]/[ストリーム名]/manifest**_mv[セグメントアドレス方式]**.mpd

**[セグメントアドレス方式]**には、以下のいずれかを指定します。

* **mvtime**: セグメント テンプレート (時間ベース) 方式
* **mvlist**: セグメント リスト方式
* **mvnumber**: セグメント テンプレート (セグメント番号ベース) 方式

> **_mv[セグメント形式]** の指定がない場合は、**mvtime** が既定値となります。

## MPEG-DASH セグメントの長さについて

Wowza Streaming Engine では、MPEG-DASH ストリーミングを行うためにビデオファイルをセグメントに分割してプレイヤーに提供します。

分割するセグメントの長さは、既定では 10 秒 (10000 ミリ秒) となっていますが、
以下のアプリケーション プロパティを変更することでセグメントの長さをカスタマイズすることができます。

> 注意
>
> MPEG-DASH アダプティブストリーミングが正しく動作するには、ビデオセグメントの始まりは必ずキーフレーム (I-フレーム) で開始する必要があり、
> ビデオセグメントの境界は キーフレームの間隔と整合性がとれている必要があります。
> 例えば、10秒のビデオセグメントの場合、2秒、2.5秒、5秒、10秒などのキーフレーム間隔でエンコードされたビデオを入力する必要があります。
> これにより、再生中に異なるビットレートや解像度のビデオストリーム間で再生の切り替えを正しく行うことができます。
>
> このため、Wowza Streaming Engine に入力するビデオ (VOD ファイルやライブストリーム) は、指定するセグメントの長さに気を付けて入力する必要があります。

### VOD ストリーミングのセグメントの長さの設定パラメーター

VOD アプリケーションの `Application.xml` (`/usr/local/WowzaStreamingEngine/conf/[アプリ名]/Application.xml`) の
以下の項目を設定することで、MPEG-DASH VOD ストリーミングのセグメントの長さを変更することができます。

| 項目 | 内容 |
| --- | --- |
| XML パス | /Root/Application/HTTPStreamer |
| プロパティ名 (Name) | mpegdashSegmentDurationTarget (バージョン 4.7.8 以降) |
| プロパティのタイプ (Type) | Integer |
| プロパティの値 (Value) の説明 | セグメントの長さ (ミリ秒) を指定する (既定値: 10000) |

### ライブストリーミングのセグメントの長さの設定パラメーター

ライブ入力デバイス等からのオーディオ・ビデオ パケットは、 Wowza Streaming Engine で時刻に基づいてセグメントに分割されます。
各セグメントの長さは、`mpegdashSegmentDurationTarget` プロパティによって制御されます。
セグメントは、作成時にアクセス可能なセグメント リストに追加されます。
リストに格納される項目の最大数は、`mpegdashMaxSegmentCount` プロパティによって制御されます。
MPEG-DASH クライアント (プレイヤー) がストリームを要求すると、Wowza Streaming Engine は最近追加された n 個のセグメントを含むマニフェストを提供します。
マニフェストで返されるアイテムの数 (n) は、`mpegdashPlaylistSegmentCount` プロパティによって制御されます。

また、ライブストリーム リピーター システムは、オリジン/エッジの構成で単一のライブストリームを複数のエッジ サーバーに配信するために使用されます。
エッジ サーバーは、ライブストリームを最初に要求するときに、オリジンへセグメント化されたライブストリームのリクエストを行って、クライアントに配信します。
`mpegdashRepeaterSegmentCount` プロパティは、最初の接続後すぐにオリジンからエッジに送信されるセグメントの数を制御します。
`mpegdashRepeaterSegmentCount` は `mpegdashPlaylistSegmentCount` 以上で `mpegdashMaxSegmentCount` 未満であることが最適です。
この設定パラメーターは、**Live Edge** タイプのアプリケーションでリピーター構成となっている場合に利用します。

ライブアプリケーションの `Application.xml` (`/usr/local/WowzaStreamingEngine/conf/[アプリ名]/Application.xml`) の
以下の項目を設定することで、MPEG-DASH ライブストリーミングのセグメントの長さを変更することができます。

| 項目 | 内容 |
| --- | --- |
| XML パス | /Root/Application/LiveStreamPacketizer |
| プロパティ名 (Name) | mpegdashSegmentDurationTarget (バージョン 4.7.8 以降) |
| プロパティのタイプ (Type) | Integer |
| プロパティの値 (Value) の説明 | セグメントの長さ (ミリ秒) を指定する (既定値: 10000) |

| 項目 | 内容 |
| --- | --- |
| XML パス | /Root/Application/LiveStreamPacketizer |
| プロパティ名 (Name) | mpegdashMaxChunkCount (バージョン 4.7.8 以降) |
| プロパティのタイプ (Type) | Integer |
| プロパティの値 (Value) の説明 | WSE 内部で格納する有効なライブストリームのセグメント数を指定する (既定値: 10) |

| 項目 | 内容 |
| --- | --- |
| XML パス | /Root/Application/LiveStreamPacketizer |
| プロパティ名 (Name) | mpegdashPlaylistChunkCount (バージョン 4.7.8 以降) |
| プロパティのタイプ (Type) | Integer |
| プロパティの値 (Value) の説明 | プレイリストで提供するライブストリームのセグメント数を指定する (既定値: 5) |

| 項目 | 内容 |
| --- | --- |
| XML パス | /Root/Application/LiveStreamPacketizer |
| プロパティ名 (Name) | mpegdashRepeaterSegmentCount (バージョン 4.7.8 以降) |
| プロパティのタイプ (Type) | Integer |
| プロパティの値 (Value) の説明 | エッジからオリジンへの最初の接続後、オリジンからエッジにすぐに送信されるセグメント数を指定する (既定値: 5) |

## MPD リダイレクト

サーバーの使用状況の分析や監視を行うための統計情報を提供するために、
Wowza Streaming Engine はそれぞれのストリーミング再生セッションについて HTTP セッション コンテキストを保存します。

通常の HTTP ストリーミング技術では、プレーヤーがマニフェストを要求したときにセッションが作成されるようになっていて、サーバーはプレイヤーが同じ再生セッションで同じマニフェストに対して追加のリクエストを行うことを期待していません。もし同じマニフェストに対してリクエストがあると新しいセッションが作成されますが、これは別の再生セッションとなります。

しかし、MPEG-DASH ライブストリーミングの場合は、プレーヤーが (MPEG-DASH の設計上の理由により) 定期的にDASH MPD マニフェストを再リクエストして、新しいセグメントの発行や古いセグメントの有効期限を識別する必要があります。すると、プレーヤーが DASH MPD マニフェストを再リクエストするたびに新しい HTTP セッションが誤って作成されてしまいます。

Wowza Streaming Engine では、**MPD.Location リダイレクト機能** (MPD マニフェスト内部のリダイレクトのメカニズム) か **HTTP リダイレクト機能**を使用することによりこの問題に対処することができます。

### MPD.Location リダイレクト機能

MPD.Location リダイレクト機能は、HTTP リダイレクトと同様の機能を提供する MPEG-DASH MPD マニフェストの `MPD.Location` 要素のサポートにより、
以下のように実現されています。

* `MPD.Location` 要素は、オリジナルの MPD URL のファイル名に Wowza セッション ID を埋め込んだ 更新された MPD URL を提供します
* プレーヤーは、そのセッション中の以降のすべての MPD リクエストに対して、更新された MPD URL を使用するようになります
* `MPD.Location` 要素は、最初の MPD だけでなく、以降のすべての MPD の中で提供されます
* 新しいセッションは、リクエストされた MPD URL に Wowza セッション ID が含まれない MPD URL へのリクエストに対してのみ作成されます
  * それ以外の場合、サーバーはリクエストに含まれる Wowza セッション ID を使用し、同じ HTTP セッション内で続行します

> 例えば、元の MPD URL が以下の場合は、
>
> http://[アドレス]:1935/[アプリケーション名]/mp4:sample.mp4/manifest_mpm4sav_mvlist.mpd
>
> 新しい URL は次のようになります。
>
> http://[アドレス]:1935/[アプリケーション名]/mp4:sample.mp4/manifest_mpm4sav_mvlist_w1499067310.mpd
>
> w1499067310 は埋め込まれた Wowza セッション ID となります。

### MPD HTTP リダイレクト機能

MPEG-DASH MPD HTTP リダイレクト機能を使用すると、Wowza Streaming Engine はプレーヤーからの最初の DASH MPD リクエスト
に HTTP リダイレクト ステータス コード (302, 307 等) で応答するように構成されます。

* HTTP リダイレクトのレスポンスに含まれる Location ヘッダーは、MPD URL のファイル名に Wowza セッションID が埋め込まれた、更新された MPD URL を提供します
* プレーヤーは、そのセッション中の以降のすべての MPD リクエストに新しい URL を使用するようになります
* 正しいサーバーが HTTP セッションを作成/管理 (その後、必要に応じてサーバーが MPD URL リダイレクトを実行) するよう、サーバー側の API 呼び出し (`httpSession.redirectSession()`) を介して実装されたリダイレクト機能は、MPEG-DASH ストリーミングのセッションに関連するリダイレクトの前に実行されます
* このリダイレクトの仕組みが期待する効果を発揮するためには、リダイレクト後の MPD URL がプレーヤーで保存されて、その再生セッション中の以降のすべての MPD リクエストにその URL が使用される必要があります
  > Wowza セッションID の情報を持たない元の MPD URL をセッションで再度使用してはいけません
* 新しいセッションは、リクエストさえれた MPD URL に Wowza セッション ID の情報が含まれない MPD URL に対してのみ作成され、それ以外の場合、サーバーは提供されたセッション ID を使用して、同じ HTTP セッション内で続行します
* 既定では、HTTP リダイレクトは 307 (一時リダイレクト) ステータスコードを使用します
  * HTTP 1.0 リクエストの場合、サーバーは 302 リダイレクト ステータスコードで上書きします
  * `mpegdashHttpRedirectDisableStatusCode302Override`, `mpegdashHttpRedirectDefaultStatusCode` プロパティを使って、既定の動作を変更できます

DASH MPD HTTP リダイレクト機能を有効にするには、`mpegdashHttpRedirectEnabled` プロパティを使って構成します。

以下、HTTPリダイレクト機能のパラメーターに関する情報です。

| プロパティ名 (Name) | プロパティのタイプ (Type) | プロパティの値 (Value) の説明 |
| --- | --- | --- |
| mpegdashHttpRedirectEnabled | Boolean | **true** に設定すると MPEG-DASH MPD ファイルの HTTP リダイレクトが有効になります: 既定値は **false** です |
| mpegdashHttpRedirectDefaultStatusCode | Integer | MPEG-DASH MPD ファイルの HTTP リダイレクト応答で使用されるデフォルトのリダイレクト ステータス コードを指定します: 既定値は **307** (一時的なリダイレクト) です |
| mpegdashHttpRedirectDisableStatusCode302Override | Boolean | "HTTP 1.0" プロトコルの DASH MPD の HTTP 要求は、通常、上記のリダイレクト ステータス コードではなく、302 リダイレクト ステータス コードで応答します。このプロパティを **true** に設定すると、そのオーバーライドを無効にして、通常のステータス コードを使用することができます: 既定値は **false** です |

## その他の設定パラーメーターについて

以下のパラメーターが Wowza Streaming Engine でのMPEG-DASH ストリーミングのカスタマイズのために用意されています。

### XML パスが `/Root/Application/HTTPStreamer` のパラメーター

| プロパティ名 (Name) | プロパティのタイプ (Type) | プロパティの値 (Value) の説明 |
| --- | --- | --- |
| mpegdashAdjustCTTSForFirstKeyFrameToZero (バージョン 4.5.0 以降) | Boolean | **true** に設定すると、VODファイル内のすべてのエンコードされたフレームの CompositionTimeToSample (CTTS) を調整して、MPEG-DASH プレーヤーでの再生を有効にします。このプロパティが設定されていない場合、または、設定されていても値が **false** に設定されている場合、ビデオの最初のフレームに CTTS 値があると、Wowza Streaming Engine は次のメッセージを `[install-dir]/logs/wowzastreamingengine_access.log` ファイルに記録します : `MediaReaderH264MPEGDash.indexFile[vod/definst/earnings_release_1q16.mp4]: First frame of video has a non-zero CTTS value [200], playback may not work on all browsers, try setting HTTPStreamer/Properties boolean property mpegdashAdjustCTTSForFirstKeyFrameToZero to true` |
| mpegdashEnableUTCTimingElements | Boolean | **false** に設定すると、ライブストリーミングの MPEG-DASH MPD マニフェストファイルの UTCTiming 要素を削除します: 既定値は **true** です (MPD マニフェストファイルに UTCTiming 要素が含まれます) |
| mpegdashUTCTimingSchemeOrder (バージョン 4.7.0 以降) | String | UTCTiming スキームを順序付けで有効にするための、優先順位が付けられたコンマ区切りのリストを指定します (リストの最初のものが最も優先されます)。有効な値は、`direct`, `http-head`、`http-xsdate`、`http-iso`、`http-ntp`、`ntp`、`sntp` です。既定値は `direct` です (ほとんどの場合この値で問題ありません)。<br/>注意: `direct` または `http-head` 以外の値を指定する場合、対応する mpegdashUTCTiming`[スキーム名]` プロパティを構成する必要があります。例えば、`http-xsdate` を指定する場合は、`mpegdashUTCTimingHttpXsDateList` プロパティを構成する必要があります。|
| mpegdashUTCTimingHttpHeadList (バージョン 4.7.0 以降) | String | HTTP ヘッダー内の日付情報を取得するために HTTP HEAD 要求を行うことができる HTTP URL の優先順のコンマ区切りリストを指定します (リストの最初のものが最も優先されます)。任意の有効な HTTP/HTTPS サーバー URL を指定します: 既定値は ローカルの Wowza Streaming Engine サーバー (`${com.wowza.wms.context.ApplicationInstance.MPEGDash.domain}/dashtime.txt`) を指す URLです |
| mpegdashUTCTimingHttpXsDateList (バージョン 4.7.0 以降) | String | 適切な時間を取得するためにリクエストを送信できる HTTP URL の優先順のコンマ区切りリストを指定します。時刻は `xs:dateTime` 形式で返されます。任意の有効な HTTP/HTTPS サーバー URL を指定します。例えば、http://myPublicServer.com/xsdate、https://mySecureServer.com/xsdate です: 既定値は `null` です |
| mpegdashUTCTimingHttpISOList (バージョン 4.7.0 以降) | String | 適切な時間を取得するためにリクエストを送信できる HTTP URL の優先順のコンマ区切りリストを指定します。時刻は ISO タイム コード形式で返されます。任意の有効な HTTP/HTTPS サーバー URL を指定します。例えば、http://myPublicServer.com/xsdate、https://mySecureServer.com/xsdate です: 既定値は `null` です |
| mpegdashUTCTimingHttpNTPList (バージョン 4.7.0 以降) | String | 適切な時間を取得するためにリクエストを送信できる HTTP URL の優先順のコンマ区切りリストを指定します。時刻は NTP タイムスタンプ形式で返されます。任意の有効な HTTP/HTTPS サーバー URL を指定します。例えば、http://myPublicServer.com/ntptime、https://mySecureServer.com/ntptime です: 既定値は `null` です |
| mpegdashUTCTimingNTPList (バージョン 4.7.0 以降) | String | 適切な時刻を取得するために NTP プロトコル (IETF RFC 5905 で定義) が利用可能な優先順位が付けられたコンマ区切りのサーバーのリストを指定します。有効な NTP サーバー名または IP アドレスを指定します。例えば、time-a.nist.gov、time-b.nist.gov、129.6.15.29 です: 既定値は `null` です |
| mpegdashUTCTimingSNTPList (バージョン 4.7.0 以降) | String | 適切な時刻を取得するために SNTP プロトコル (IETF RFC 5905 で定義) が利用可能な優先順位が付けられたコンマ区切りのサーバーのリストを指定します。有効な SNTP サーバー名または IP アドレスを指定します。例えば、time-a.nist.gov、time-b.nist.gov、129.6.15.29 です: 既定値は `null` です |

### XML パスが `/Root/Application` のパラメーター

| プロパティ名 (Name) | プロパティのタイプ (Type) | プロパティの値 (Value) の説明 |
| --- | --- | --- |
| mpegdashMinBufferTime (バージョン 4.5.0 以降) | Integer | MPEG-DASH MPD の minBufferTime 属性を変更します: 既定値は **6000** (ライブ ストリームの場合) または **1500** (VODストリームの場合) です |
| mpegdashAddMPDSegmentBaseURL (バージョン 4.6.0 以降) | Boolean | `<BaseURL>` タグを MPD に含めるかどうかを制御します。 `<BaseURL>` の挿入を有効にするには値を **true** に設定します: 既定値 false です |