AWS Media Servicesやってみた

最近、AWSが怒涛のリリースラッシュですね

# 目的
:grin:2017/11にリリースされたAWSの動画配信インフラ メディアサービスを使って、簡単に動画配信したい。

できる限り遅延は無い方向で！ まずざっくりとした使い方を把握して、どの程度、細かく設定できるのか知りたい！
( 実際のスマホでの確認までではなく、PC上でエンコードされたライブが見えるところまでが今回のゴール )

# 作りたいシステム構成
ライブカメラ -> Wirecast -> RTMP(ないしRTSP) -> エンコーダー -> CDN -> ユーザ

CDN使うと大規模に安く配信できるので使いたい。が、当然できる限り遅延は少なくしたい。

# 感想 :grinning: :scream: 
シンガポールリージョンと離れていることが原因なのか、私の遅延縮小テクニックのレベルが低いのか、まだ遅延が数十秒ある。

でも結構、細かいところまで設定可能なので、前向きに検討したい！
あとマルチビットレートの設定が最初から入っているのとか、冗長化を初めから考慮されてる設定は素敵。
2017/12/04時点では、MediaPackageで選択可能な配信フォーマットはHLSのみでした。Mpeg-DASHとか必要な場合は、対応待ちです。

ただ、UIというか画面遷移が迷うところが多いし、一通り設定が完了しないと、
カメラからのデータを送れないしで、挫けそうになりました。この辺は時間が解決してくれるよ！という気持ちで。

# 背景:deciduous_tree:
EC2でwowzaやAdobeMediaServer立てて運用するのはもちろんありだし、カスタマイズ性はこちらの方が高そうではある(インスタンスプランも選択できるし)
が、運用コストはかかるのでありできれば減らしたい。

# :tada:AWSメディアサービスって?(複数サービスの集合でした)
参考 [クラウドベースの映像処理、保存、収益化](https://aws.amazon.com/jp/blogs/news/aws-media-services-process-store-and-monetize-cloud-based-video/)
     [classmethod様](https://dev.classmethod.jp/cloud/aws/aws-media-services/)

2017/12現在、MediaConvert、MediaLive、MediaPackage、MediaStore、MediaTailorという5つのサービスで構成されています。
このうち、自分に必要そうな『MediaLive』『MediaPackage』のみを使ってみました。
VOD、および他動画解析サービスなどと連携する場合はS3に保存するMediaStoreも併せて使う必要があるかもしれません。

# 設定方法:baby_chick:
## MediaLiveについて
(先に MediaPackageから設定する必要があります )
当初、名前にLiveってあるし、MediaLiveだけで完結できるか?と思いきやできず...
なんか、CDNから見えるはずのオリジンサーバに該当する設定が無くね? どこで作るの? と見つからなかった。
MediaLiveは「カメラから入ってきたデータをエンコードしてPushする」という機能までなので、
それを「CDNなどからPullするための機能は『MediaPackage』が担当する」という事に気づかなかった。ので先にMediaPackageの設定から行う必要があります。

## MediaPackage:movie_camera:
CDNなどから参照されるものは「チャンネル」と呼ばれます。これを冗長化のために2つ作成します。

下記のように進めます( 私は近場のシンガポールを選択しましたが、お好みで )
* 右上のリージョンの選択で[ シンガポール ]を選択
* 左上の[ サービス ]から[ MediaPackage ]->[ Create ]
チャンネルの詳細, Channel details で
* ID 任意
* Input typeは[ Apple HLS ]、そのまま
[ Create ]をクリック

これを2つ作成してください(MediaLiveは冗長化が前提のようです)

## MediaLive:cinema:
ビデオからの入力を受けるため、まず
* [ Input security groups ]( CIDRでアクセス制限できる )
* [ Input ] カメラからクラウド側に送る設定。 RTP, RTMP(push), RTMP(pull), HLS でインプットできる。私はRTMP(push)でRTMP用エンドポイントを作成
が必要です。

### :fire:Input security groups:fire:
[ MediaLive ]->[ Input security groups ]->[ Create input security group ]
テキストフィールドの中に CIDRで許可するカメラ側のIPアドレスを記載します。
回線冗長化などで、複数IPアドレスを許可する時はカンマか改行で分けます。[ Create ]でアクセス制限を作成。

### Input
[ MediaLive ]->[ Input ]->[ Create input ]
* Input name 任意
* Input type RTP, RTMP(push), RTMP(pull), HLSが選択可能

* Input security group
[ Use existing ]->プルダウンメニューから先程作成した Input security group を選択

* Input destinations
これはクラウド側のRTMP受け側の冗長化のための設定です。
Destination A -> a
Destination B -> b
としました(このクラウド側のRTMPエンドポイントの設定は後ほどWirecastの設定で使います)

### Channels:tv:( エンコード設定 )
[ MediaLive ]->[ Channels ]->[ Create a Channel ]
* Channel name 任意
* IAM role (ここでは、最初、必要なIAM roleが無い場合は作成するウィザードを起動可能だった記憶が...)
 IAM roleを作成すると[ MediaLiveAccessRole ]というromeが作成され、プルダウンメニューから選択可能になります。

* Channel template いくつか選択可能。ただ自分でチャンネルを作成すると、プルダウンメニューにそれが現れ、それを元に作成できます。
 余談ですが、これテンプレートから選択すると、上のIAM roleの設定内容、チャンネル名がクリアされちゃいます。私はLiveを選択しました。
 この点、直感的でないので、UI変わるんじゃないかなー、と。
 ので、テンプレートから選択したら、チャンネル名とIAMロールの設定を直す必要があります。

* Attach input
 先程作成した、input設定をプルダウンメニューから選択。

* Input setting
これはそのままにしました。

#### ( 左側のメニュー )[ Output group ] 出力全体にかかる設定
出力全体にかかる HD( HLS )をクリックします。
配信動画のエンコーディング設定です。 

* HLS Group destination A
* HLS Group destination B 


最初、ここで凄く悩みました。
これですが、MediaLiveでRTMP(push)を選択した時に、更に「どこへpushするか」の設定です。
AkamaiはこのRTMP(push)をダイレクトに受けられるようですが、弊社できればCloudFront使いたい事情が...
このため、私の環境ではMediaPackageが必要になりました。

MediaPackageで作成した2つのチャンネルがここで生きてきます。 MediaPackageのページを開き、
それぞれのチャンネルの[ URL ]をコピペして、この[ HLS Group destination {A,B} ]
にそれぞれ入力します。

##### [ HLS Settings ]
* CDN Settings ->[ Hls basic put ]

##### [ HLS Outputs ]マルチビットレートでの動画配信の設定で重要ですが、後述します
私の環境では 60フレームの配信テストは不要だと思ったので[ _720p60 ]は[ x ]のリンクから削除しました。

##### [ Manifest and Segments ] m3u8ファイルの設定
* Mode TSファイルにつけられるインデックスを再利用するか
 * vod インデックスを再利用しない
 * live インデックスを再利用する
 これ、インデックス再利用した時にはTTLの設定が重要になったりするやつ? 最初は検証という事でvodを選択、

* Segment Length デフォルト6 -> 1秒に変更。低遅延を狙う。

* Num Segments .m3u8ファイル内のセグメントの個数の設定。デフォルト10 -> 5個。これも低遅延。
 ただ、実際には、このパラメータを変更しても.m3u8内のセグメント個数が減らず、LivePackage側の設定変更が必要でした.

* Keep Segments 説明を見ると [ Mode ]が[ live ]である時に効果があるパラメータ、らしい。liveの時にはセグメントごとにつけられるインデックスが再利用されるが、何個まで保持するか、という設定らしい

m3u8関連の設定は、上記程度で終わり。

##### [ HLS Outputs ]マルチビットレートの設定
左側のメニューに現れる[ Output 1 ][ Output 2 ][ Output 3 ]などのリンクをクリック。
低遅延を狙いたいので[ GOP Structure ]->[ GOP Size ] を 60 -> 30 に変更しました。
( これは私の考えが間違ってたら指摘いただきたいのですが )キーフレームが短い方が早く配信がスタートするような。
RTMP送信側のキーフレームも併せて短くする必要がありますが。

##### [ Create ]でChannelを作成します
でも、まだクラウド側の配信設備がスタートした訳じゃないので注意

### 配信スタート:tada:
チャンネル設定が済んでいる状態で[ MediaLive ]->[ Channels ]->作成したチャンネルのラジオボタンをクリック->[ Start ]
ではじめてスタートします。

これ最初、気が付かなくて「あれー、wirecastで設定しても、クラウド側に繋がらないよ。
というかクラウド側に telnet クラウド側IPアドレス 1935 してもポート空いてない... これ、何? ファイアウォール? とかで数時間消えたので、皆さんお気をつけください。

ちなみにクラウド側のRTMPのIPアドレスは[ MediaLive ]->[ Inputs ]->[ Endpoints ]で確認できます。
この設定はWirecastでも必要になります。

チャンネルをスタートすると、[ Details ]->[ Inputs ]に、紐づく[ Inputs ]へのリンクがありますのでクリック。
[ Inputs ]の画面に遷移します。[ Endpoints ]でクラウド側のRTMPのエンドポイントが分かりました。

これをWirecastに設定し、カメラからのデータを送り込んでみましょう！

一応、
カメラ -> Wirecast -> MediaLive -> MediaPackage の接続ができたハズです！

# カメラからのデータを見てみる:tv:
[ MediaPackage ]->作成したチャンネル->[ Endpoints ]に移動します。
[ Play ]をクリック。PC上で動画の確認ができましたでしょうか?