他のエンコーダーでトランスコードした MP4 ファイルを Azure Media Services で VOD として配信する方法

#このドキュメントでやっていること
Azure Media Services の Streaming Endpoint の Dynamic Packaging の機能を利用して、マルチビットレートの動画を HLS / DASH / Smooth のそれぞれのストリーミング形式で配信をするにあたり、その原盤になるファイルを **「Azure Media Services の Encoder なしに」** 作る方法の実験の結果をまとめました。

#前提
Microsoft Azure の Media Services を使うと、ライブ配信とビデオオンデマンドの両方をクラウド上の PaaS にて実現できます。今回は、このうちの VOD についての話です。

## Azure Media Service を使った VOD 配信について
Azure Media Services では、クラウド上のストレージに Multiple Bitrate でトランスコード済みの MP4 動画ファイルを配置しアセットとして登録することで、VOD 配信が可能です。プログレッシブダウンロードと HLS / MPEG-Dash / SmoothStreaming の 3 つのストリーミング形式でダイナミックパッケージングが可能なため、ビデオをアップロードしてアセットとして登録する段階で、配信先の端末の再生可能なフォーマットを意識しなくても良いのがとても良いところです。

[Media Services の用語と概念](https://docs.microsoft.com/ja-jp/azure/media-services/latest/concepts-overview)
[Azure Media Services のストリーミング エンドポイント (配信元)](https://docs.microsoft.com/ja-jp/azure/media-services/latest/stream-streaming-endpoint-concept)

### 公式ドキュメントより引用
> ストリーミング エンドポイント は、ダイナミック (Just-In-Time) パッケージおよび配信元サービスを表します。これは、ライブのオンデマンド コンテンツをクライアント プレーヤー アプリケーションに直接配信できます。 一般的なストリーミング メディア プロトコル (HLS または DASH) のいずれかを使用します。 さらに、ストリーミング エンドポイント は、業界有数のデジタル著作権管理 (DRM) に動的 (Just-In-Time) 暗号化を提供します。

> メディア ストリーミング業界では、このサービスは、一般的に パッケージャー または 配信元 と呼ばれます。 この機能に関するその他の一般的な業界用語には、JITP (Just-in-time-packager) や JITE (Just-in-time-encryption) があります。

#一般的な手順
一般的には、Azure Media Service の機能だけで実現する方が楽です。

C# の場合の手順はこちら。
[チュートリアル:Media Services v3 を使用してビデオをアップロード、エンコード、ストリーム配信する](https://docs.microsoft.com/ja-jp/azure/media-services/latest/stream-files-tutorial-with-api)

他の言語でもだいたいこんな感じです。

1. 空の入力用アセットを作成する
1. 作ったアセットに入力元となる動画ファイルをアップロード
1. エンコード結果を格納する出力用のアセットを作成する
1. 動画ファイルを Media Service の Encoder にて Multi Bitrate の MP4 ファイルにエンコードする
1. 出力用アセットにストリーミングロケーターを紐づける

#今回やりたいこと
**「Media Service の Encoder を使わずに、Azure Media Services を利用して VOD 配信が可能な Multi Bitrate の動画データとアセットを作りたい。」**

（例えばこんな要件の時に使えるかも… : 別の動画配信サービスからの移植案件で、既に Multi Bitrate の MP4 ファイルは存在しており、Azure Media Services に動画データを移動することは出来るが、再エンコードは移行コストを鑑みて出来ればかけたくない。）

#解決するためにやってみたこと
##Azure Media Services Explorer のインストールと、Media Service への接続
今回は、Media Service への操作を GUI で簡易に行うため、[Azure Media Services Explorer](https://github.com/Azure/Azure-Media-Services-Explorer) のインストールと、Media Service への接続を事前に済ませました。

ツールのダウンロードはこちらから。使い方については割愛します。
[Azure Media Service Explorer / Release](https://github.com/Azure/Azure-Media-Services-Explorer/releases)

なお、日本語 OS で起動すると、日本語ロケールで読み込まれますが、たまに文字列リソースが収まりきらずにデザインが崩れています。
ショートカットに **/language:en** のコマンド引数をつけると、英語版で起動してくるのでおススメ。

##ドキュメント調査
まずは Azure Media Services の Dynamic Package を攻略せねばいかんので、ドキュメントを確認します。
[Media Services v3 のダイナミック パッケージ](https://docs.microsoft.com/ja-jp/azure/media-services/latest/encode-dynamic-packaging-concept)

> ダイナミック パッケージを活用するには、中間 (ソース) ファイルを一連の複数ビットレート MP4 (ISO Base Media 14496-12) ファイルにエンコードする必要があります。 エンコードされた MP4 を含む資産と、Media Services のダイナミック パッケージで必要とされるストリーミング構成ファイルが必要です。 

~~ストリーミング構成ファイルというのがよくわかりませんが~~ とりあえず先に進みましょう。

##Multi Bitrate の MP4 ファイルを準備
ドキュメントを読む限り、とりあえずは規格に合った形の MP4 ファイルが各ビットレート毎に必要な模様です。

というわけで ffmpeg を使ってサクッと作りましょう。下記のコマンドを用意したいビットレートラダーの分だけ回せば OK ですね。

```shell
ffmpeg -i 入力ファイル -vb ビットレート 出力ファイル名
```

既存の ISO Base Media 14496-12 でエンコードされた Multi Bitrate の MP4 ファイルがある方はそれを使っても大丈夫だと思います。

## アセットの作成、そしてファイルのアップロード
Azure Media Services Explorer を利用し、空の[アセット](https://docs.microsoft.com/ja-jp/azure/media-services/latest/assets-concept)を作成。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199379/dff4f79d-0984-28c6-fd95-719231fd54ae.png)


そこにビットレートラダーごとの MP4 ファイルを投入。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199379/5af1780c-b388-451d-a46a-4aa7a6e6560a.png)

今回は 2M/1.5M/1M/700k/500k の 5 段階のビットレートラダーを切りました。

## ストリーミング構成ファイルを作成
ドキュメントを読んでいても、以下のようにしか書いていなくて「ストリーミング構成ファイルってなんぞや」でハマりましたが、Media Services Explorer の画面にヒントがありました

>エンコードされた MP4 を含む資産と、Media Services のダイナミック パッケージで必要とされるストリーミング構成ファイルが必要です。

一個前のスクリーンショットを見ていただくと、"Generate a Server Manifest" と "Generate a Client Manifest" という二つのボタンがあることがわかります。拡張子 ism と ismc のファイルを生成するようですので、これは [Smooth Streaming](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-sstr/8383f27f-7efe-4c60-832a-387274457251) のお作法に従ったマニフェストを書けばいい、ということが予想できます。

今回は、ツールの力を借りるべく、"Generate a Server Manifest" と "Generate a Client Manifest" を順番に押してみました。どっちもボタンを押して開いたマニフェストのテンプレートをそのまま保存してもとりあえずは使えます。必要な設定があるなら、Smooth Streaming の仕様に従い行いましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199379/27a0e5af-3f04-36e2-a93d-383675cc9d70.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199379/5f029545-0336-32fd-650a-60c3836ca1b8.png)

## ストリーミングロケーターを割り当てる
ここまで作業をすると、先ほど作った空のアセットが、Media Service Explorer のビューからも Multi Bitrate MP4 として認識されているはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199379/daa8deca-d6c3-0081-66aa-e4b13762d384.png)

アセットを右クリックし、出てきたメニューから "Publish" → "Create a Streaming Locator" で VOD 配信を行うためのロケーターを割り当てます。

表示された画面では、今回はストリーミング形式での VOD のみ行いたいので、"Clear Streaming" を選び、ロケーターを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199379/ac12adcb-ff3b-2ebb-9f03-271cf718cdff.png)

すると、HLS / DASH / Smooth それぞれのマニフェストファイルへのパスが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199379/ead06125-73a8-7f62-11b9-b6dcce143977.png)


あとは、お好みのプレイヤーに、お好みの再生方式のマニフェストを食わせてあげれば、Dynamic Packaging によって、ひとつの Multiple Bitrate MP4 の元データをもとに、様々なデバイスで再生可能な動画のストリーミングが可能になります。

MPEG-DASH のリファレンスプレイヤーを使って再生してみましたが、ちゃんと Multiple Bitrate 
も効いていて、再生開始時には低めのビットレートから読み込みはじめ、だんだんと最大ビットレートの 2000kbps まで上がっていることもわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199379/202304a4-3b5a-d1e1-8183-c2474733f8d5.png)

#まとめ
可能であれば、Single Bitrate の入力ファイルを用意していただき、Azure Media Services のエンコーダーを使って Multi Bitrate の MP4 ファイルにトランスコードを行うのが、一番楽で一番安心な方法にはなると思います。

[Media Services を使用したビデオとオーディオのエンコード](https://docs.microsoft.com/ja-jp/azure/media-services/latest/encode-concept)

ただ、別のクラウドやオンプレミスからの移行案件などで、それが出来ない場合もあると思いますので、その際にはこの知見が役に立てば幸いです。

#免責事項 (Discraimer)
公式ドキュメントをあたったわけではなく、経験的に作業を進めている部分もあるため、このドキュメントの記載内容の利用については、自己責任にてお願いします。