AWS Elemental MediaConvert による HLS 動画の生成

# [AWS Elemental MediaConvert](https://aws.amazon.com/jp/mediaconvert/) とは
AWSの提供しているフルマネージド動画変換サービスです。
この記事では、MediaConvertを使ってあらかじめ用意されたMP4動画をストリーミング配信に適したHLS形式に変換する方法をみていきます。


# HTTP Live Streaming (HLS) とは
HTTPを用いた動画のストリーミング手法のひとつです。

プレイリストになるM3Uファイル `.m3u8` と各セグメントになる動画ファイルを用意し、クライアント側はプレイリストの指示どおりに動画を読み込み連続して再生することでひとつの動画に見える……という方式です。

セグメントの動画ファイルはH.264+AACをMPEG-2 TSコンテナに格納した形式が一般的です。

## ファイル群の構成例
HLSでの動画は、セグメントごとの動画ファイル、それらをひとまとめにしたプレイリスト、複数プレイリストの情報を収めたマスタープレイリスト、で構成されます。

```
/
|- 114592f2fdb9444db61f9bab30da7410.m3u8  # マスタープレイリスト
|- 114592f2fdb9444db61f9bab30da7410_main.m3u8  # プレイリスト1
|- 114592f2fdb9444db61f9bab30da7410_main_00001.ts  # セグメント1-1
|- 114592f2fdb9444db61f9bab30da7410_main_00002.ts  # セグメント1-2
...
```

ビットレート違いの動画で構成された複数のプレイリストを作成しておき、そのプレイリストの情報をマスタープレイリストに列挙しておくとクライアント側が帯域に応じて再生するプレイリストを動的に変化させることができます。

## MediaConvert 用のロールを作成
MediaConvert を信頼するエンティティにしたロールを作成します。

1. IAMコンソールからロールのページを開き、『ロールの作成』をクリック
2. 『このロールを使用するサービスを選択』から『MediaConvert』を選択し、『次のステップ: アクセス権限』をクリック
3. 『次のステップ: 確認』をクリック
4. 『ロール名』を適当に定め、『ロールの作成』をクリック


## 変換したい動画ファイルをS3に配置
MediaConvertは変換元・変換先のファイルをS3から読み取り・配置するので、バケットを1つ以上用意する必要があります。
変換元ファイルと変換結果のファイルを同じバケットに格納することも可能です。


## ジョブテンプレートの作成
直接パラメータを設定して変換ジョブを生成することも可能ですが、今回はあらかじめパラメータを決めてジョブテンプレートを作成してから変換を行ってみることにします。

1. 『テンプレートを作成』
2. 『General Information』に名前と説明を入力。
3. 『入力』の『追加』をクリック。必要であれば設定を変更してください。存在する項目の意味がわからない人はおそらく手を加える必要のない人です。
4. 『出力グループ』の『追加』→『Apple HLS』
5. 『出力グループ』の『Apple HLS』を選択
    - HLS関連のオプションが表示されるので、適宜変更
6. 『出力グループ』の『Output 1』を選択
    - エンコードオプションが表示される。各オプションについては後述。
7. ページ下部の『更新』をクリック


## オプションについて
全てのオプションはジョブ生成時に上書きすることもできます。

### 出力設定
ドキュメントに詳細な記述がないことも多く、動画の知識から推測して書いている部分もあるため、間違いがあるかもしれません。
もし見つけたらぜひコメントお願いします……！

#### Preset
AWSが提供している出力プリセットをそのまま使うこともできます。

#### 名前識別子 / セグメント識別子
名前識別子は設定必須の項目です。これらを設定すると、
- マスタープレイリスト: `[入力ファイル名].m3u8`
- 各出力に対応するプレイリスト: `[入力ファイル名][名前修飾子].m3u8`
- 各出力に対応するセグメント: `[入力ファイル名][名前修飾子][セグメント修飾子].ts`

というようにファイルが生成されます。
それぞれの出力で生成されるファイル名が被らないように設定する必要があります。これはジョブテンプレートの保存のタイミングではなくジョブの生成時にエラーとなるので注意してください。

#### アドバンスト / トランスポートストリーム設定
通常は変更する必要はないと思います。ここをさわる必要のある人は項目の意味を理解している人だと思うので、説明は割愛します。

### ストリーム設定
主に基本的な設定、または重要な割に説明文が難解なものについて記述します。記述のない項目は意味がわからなければデフォルトでよいと思います。
#### ビデオコーデック
今回は `MPEG-4 AVC (H.264)` の動画を作成します。

#### 解像度
出力動画の解像度を固定にしたい場合は入力してください。空欄のままにするとパススルー（入力動画と同じ解像度で出力）になります。

#### スケーリング動作
出力の解像度を設定した場合、かつ、入力された動画の縦横比が設定のものと異なる場合に、余った部分に黒帯を挿入する (`default`) か、縦横比を無視して出力の解像度に合うようにストレッチする (`Stretch to output`) かの設定です。

#### フレームレート変換アルゴリズム
フレームレートを `Follow source` 以外に設定した場合に有効になる項目です。
- `Drop duplicate`: フレームを削ったり複製することでフレームレートを変化させる。
- `Interpolate`: 2枚のフレームを計算して1つにまとめたり、2枚のフレーム間のフレームを補間して生成することでフレームレートを変化させる。

`Interpolate` のほうが滑らかさは向上します。その分エンコード時間は増大するかもしれません。

#### レート制御モード
- `CBR`: 常に一定のビットレートになるようにエンコードします。
- `VBR`: 動きの少ないシーンではビットレート低め、激しいシーンでビットレート多くなるように、ビットレートを変動させながらエンコードします。

CBRも実際はVBRでエンコードされていて、足りない部分がパディングされている、という構造になっているようなので（[参考](http://up-cat.net/CBR%25A4%25CE%25B8%25B8%25C1%25DB.html)）、CBRにすると『最高 xxx bpsになるようにパディングしつつ動画を生成』という挙動になるはずです。
CBRが必須要件でなければVBRでエンコードするのがよいのではないでしょうか。

#### 品質チューニングレベル
- `Single Pass`: 速度優先1パスエンコード
- `Single Pass HQ`: 画質優先1パスエンコード
- `Multi Pass HQ`: 2パスエンコード

VBRでビットレート、ひいてはファイルサイズへの制約要求が強い場合は `Multi-Pass HQ` に設定するのがよいと思います。
一度動画を分析してビットレートの割り振りを決定してから実際のエンコードを行うので、1パスと比較すると平均ビットレートが低めでもよりよい画質になることが期待できます。

#### GOPサイズ
長くすれば圧縮率向上の面で有利ですが、HLSでセグメント分割を行うときはGOP単位でしか動画の分割を行えないことに注意して設定してください。

#### リファレンスフレーム間の B フレーム数
I/Pフレーム間に挿入されるBフレームの最大数（だと思います）。
大きくすれば圧縮効率はよくなりますが、大きくしてもデコード負荷の割に見返りは小さくなるので程々に。
`フレームレート / 10` くらいがバランスとれている設定ではないかと思います。

#### 参照フレームの数
増やすと圧縮効率が上がります。ただしProfile/Levelと解像度・フレームレートで最大の参照フレーム数が規定されている（[参考: 『ストアされる最大フレーム数』](https://ja.wikipedia.org/wiki/H.264)）ため、これ以下にする必要があります。



## ジョブの作成
ジョブテンプレートと変換元の動画から変換ジョブを生成してみます。
1. 『ジョブテンプレート』から作成したジョブを選択
2. 『ジョブテンプレートの詳細』画面で『ジョブの作成』をクリック
3. 『入力』→『入力1』を選択し、入力元動画になるS3上のオブジェクトのパスを設定
4. 『出力グループ』→『Apple HLS』を選択し、生成物の出力先パスを設定
    - 指定しないと入力と同じパスに生成されます
5. 『ジョブの設定』→『設定』の『IAM ロール』にMediaConvert用のロールを設定
6. ページ下部の『作成』をクリック。作成したジョブの詳細画面に飛ぶ
7. しばらく待ってから『更新』をクリックすると『ステータス』が `COMPLETE` に変化している
8. 『出力』の『Apple HLS』のリンクをクリックするとS3の成果物のパスに飛ぶ

# 生成された動画の視聴
S3バケットの公開設定が適切になされていれば、マスタープレイリストのファイルをSafari/Edge/スマートフォンのブラウザ等で開くと動画が再生されるはずです。


[次の記事](https://qiita.com/gion/items/80a63d242663ea6259de)ではLambdaとS3トリガーを用いた自動化の設定を行います。