CloudFront+S3による動画配信メモ

## はじめに
とあるプロジェクトでUnreal Engineを用いたゲーム内にて動画を埋め込み要望があり、mp4の動画ファイルを変換する必要があったのでその時のメモになります。

## 構成
配信用としてCloudFront+S3の基本構成にて実施

## MediaConvertを用いてmp4ファイルをCMAF形式に変換
UE(Electra Media Player)の場合、HLSの分割フォーマットがISO/IEC-14496-12 または CMAF セグメントとしてフォーマットされている必要がある。

>バリアント ストリームは、ISO/IEC-14496-12 または CMAF セグメントとしてフォーマットされている必要がある： ISO/IEC-13818-1 準拠の MPEG2 トランスポート ストリーム セグメントはサポートされていません。
https://docs.unrealengine.com/5.0/ja/electra-media-player-in-unreal-engine/

そのため、MediaConverterの出力グループはCMAFを指定
<img width="589" alt="スクリーンショット 2023-02-22 21.45.58.png (63.8 kB)" src="https://img.esa.io/uploads/production/attachments/10655/2023/02/22/108350/81cd4bfa-7b1b-4d17-9681-94b32d6f2058.png">

### S3 バケット作成
動画変換に用いるS3バケットを作成します。
バケット内にはそれぞれ「 input」と「output」のフォルダを作成

### inputフォルダに対象mp4をアップロード(movie.mp4)

### AWS Elemental MediaConvertで変換
- AWS Elemental MediaConvertより「ジョブの作成」を選択

- 入力1に動画ファイルへのパスを指定
今回は「s3://変換用s3バケット名/input/movie.mp4」

<img width="1057" alt="スクリーンショット 2023-07-21 10.45.58.png (144.3 kB)" src="https://img.esa.io/uploads/production/attachments/10655/2023/07/21/108350/61823c63-12c1-4c52-abc1-857175739983.png">

  - 出力グループにて追加を押下
<img width="337" alt="スクリーンショット 2023-07-21 10.47.54.png (48.2 kB)" src="https://img.esa.io/uploads/production/attachments/10655/2023/07/21/108350/af427620-d871-4c44-a60d-955d4934026c.png">

  - CMFAにチェックを入れて「選択」
<img width="585" alt="スクリーンショット 2023-07-21 10.48.04.png (155.3 kB)" src="https://img.esa.io/uploads/production/attachments/10655/2023/07/21/108350/da7e0299-a0a4-46d0-86ea-5588815e3439.png">

- 「CMAF グループの設定」項目にて以下をそれぞれ指定
- 送信先: s3://変換用s3バケット名/output/
<img width="1139" alt="スクリーンショット 2023-07-21 10.56.11.png (124.7 kB)" src="https://img.esa.io/uploads/production/attachments/10655/2023/07/21/108350/c31e23a9-55a1-45d1-a1dc-ae959e06ff70.png">

- 出力
    - output1:名前修飾子に「video」を設定
    - output2:名前修飾子に「audio」を設定

<img width="913" alt="スクリーンショット 2023-07-21 10.56.34.png (47.0 kB)" src="https://img.esa.io/uploads/production/attachments/10655/2023/07/21/108350/e1d9eb26-5f02-4f48-9cd5-f73c1d24c1c8.png">


 - 「H.264」項目にて以下をそれぞれ指定
    - 品質チューニング: シングルパスHQ
    - 最大ビットレート: 1000000
    - QVBR品質レベル: 7
      参照: https://docs.aws.amazon.com/ja_jp/mediaconvert/latest/ug/cbr-vbr-qvbr.html

<img width="1409" alt="スクリーンショット 2023-07-21 10.55.40.png (230.2 kB)" src="https://img.esa.io/uploads/production/attachments/10655/2023/07/21/108350/57186198-d9f3-42ce-969f-220dc51c0f65.png">


  - 「ジョブの設定」->「AWSの統合」を選択
      - 新しいサービスロールを作成、アクセス許可を設定
      - 新しいロール名を指定
      - S3 の入力場所: s3://s3バケット名/input/
      - S3 の出力場所: s3://s3バケット名/output/
<img width="794" alt="スクリーンショット 2023-07-21 10.55.15.png (201.6 kB)" src="https://img.esa.io/uploads/production/attachments/10655/2023/07/21/108350/c421debb-7727-4266-9963-4f9e2e8f9e0f.png">

  - 画面右下の作成を押下
<img width="312" alt="スクリーンショット 2023-07-21 11.01.06.png (18.8 kB)" src="https://img.esa.io/uploads/production/attachments/10655/2023/07/21/108350/a48f4c38-80b0-4624-b23d-b7fb884fd41b.png">

- ジョブが完了するのを待ってoutput/にファイルが出力されていることを確認
```
変換用s3バケット名/output/
├movie.m3u8
├movie.mpd
├movieaudio.cmfa
├movieaudio.m3u8
├movievideo.cmfv
└movievideo.m3u8
```

  - 出力ファイルを全て任意のバケットに移動
    - s3://配信用S3バケット/movies/

  - tips
    - AWS Elemental MediaConvertにて同様の変換ジョブ設定を用いたい場合、ジョブIDをクリックして複製を押下

## 配信用index.html作成
[video.js](https://videojs.com/)を用いて再生させます。

- srcに`CloudFrontURL/s3フォルダパス/m3u8ファイル`を指定
- `class="vjs-fluid vjs-big-play-centered`"で動画をスクリーンサイズに合わせる
- cssやjsは自前で用意してカスタマイズも可能

```html
<html>
  <head>
    <title>test</title>
    <link href="https://vjs.zencdn.net/7.15.4/video-js.css" rel="stylesheet">
  </head>
  <body>
    <video-js id=test
              class="vjs-fluid vjs-big-play-centered" controls>
      <source
         src="https://{CloudFrontURL}/movies/movie.m3u8"
         type="application/x-mpegURL">
    </video-js>
    <script src="https://vjs.zencdn.net/7.15.4/video.js"></script>
    <script>
      var player = videojs('test');
    </script>
  </body>
</html>
```

## 変換後のファイル+index.htmlファイルをS3に格納
最終的に以下のようなファイル構成になる

```
配信用s3バケット/movies/
├index.html
├movie.m3u8
├movie.mpd
├movieaudio.cmfa
├movieaudio.m3u8
├movievideo.cmfv
└movievideo.m3u8
```

## ブラウザアクセス
`https://{CloudFrontURL}/movies/index.html`にアクセスして動作確認

## おわりに
普段UE関連に触れる事がなかったこともあって、UE(Electra Media Player)特有の仕様によってCMAFとしてフォーマットされている必要があるという事に辿り着くのにやや難儀しましたが、無事ゲーム内にて動画を配信することが出来ました。

MediaConvertも便利なので是非今後も活用するシーンがあったら利用していきたいと思います。