この記事は NewsPicks Advent Calendar 2019 の8日目の記事です。
はじめに
こんにちは、NewsPicksでサーバーサイドエンジニアをしている@d-kumoです。
NewsPicksというとオリジナル記事等の文字ベースのコンテンツをイメージされる方も多いかと思いますが、動画コンテンツにも力を入れており、今では週に4回配信することもあります。
今後増えていく動画コンテンツをより安定的に配信するため、最近はいろんな配信技術に触れる機会も増えてきました。
そんな中で、今回はAWSが提供しているライブ配信サービスAWS Elemental MediaLiveを使った配信構成を試してみたのでご紹介したいと思います。
※NewsPicksの動画配信構成については、以下の記事で解説しています。ご興味のある方はご覧ください。
https://qiita.com/kirihata/items/c027c7561eead3b1dced
MediaLiveとは
AWS Elemental MediaLiveとは、入力された動画データをリアルタイムにエンコードして出力してくれるサービスです。
入力として使える動画データは、撮影中のカメラ等から転送されてきたものはもちろんのこと、S3に配置されているmp4ファイルを使うこともできます。
ただ、このサービスはエンコードしてくれるだけなので、動画配信は他のサービスと連携して行う必要があります。
例えば、AWS Elemental MediaStoreというメディア向けにチューニングされたストレージサービスをMediaLiveの出力先に指定し、そこでエンコードされたコンテンツを保存、配信するような形です。
やりたいこと
既に収録済みである動画を配信します。
具体的には以下の通りです。
- 配信構成は、MediaLive→MediaStore(冗長性は考えない)
- 入力は、S3にアップロードしたmp4ファイル
- 配信スケジュールは以下
- 2019/12/8 21:45から予告映像を配信する(ループ再生)
- 2019/12/8 22:00になったら本編映像を配信する
- 本編終了後、配信が終了した旨の映像を配信する(ループ再生)
ざっくりやること
やりたいことを実現するため、以下の設定をします。
- S3に動画ファイルを配置
- MediaStoreでコンテナ作成
- MediaLiveでInput作成
- MediaLiveでChannel作成
- MediaLiveでスケジュール設定
やってみる
S3に動画ファイルを配置
S3の適当なパスに配信したいmp4ファイルを配置します。
今回は、予告動画、本編動画、終了後動画の3本を配置しています。

MediaStoreでコンテナ作成
MediaLiveからの配信を受けるコンテナを作成します。
コンテナ作成
Create container
からコンテナを作成します。

Container policyを設定
公式ドキュメントを参考にポリシーを設定してアクセスできるようにします。
HTTPS通信であれば誰でもアクセスを許可するのであれば、以下の通りです。
<region>
、<owner acct number>
、<container name>
には適当なものを入れてください。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadOverHttps",
"Effect": "Allow",
"Action": ["mediastore:GetObject", "mediastore:DescribeObject"],
"Principal": "*",
"Resource": "arn:aws:mediastore:<region>:<owner acct number>:container/<container name>/*",
"Condition": {
"Bool": {
"aws:SecureTransport": "true"
}
}
}
]
}
MediaLiveのInput作成
MediaLiveへの入力として、S3に配置したmp4ファイルを設定します。
Create input
でinput作成画面を開きます。

Inputの名前、入力するファイル形式(今回はmp4)を入力します。

ソースのパスを指定してCreate
(Input source A
だけ入力すれば大丈夫です。)

配信する3つの動画ファイルについて、それぞれ作成します。
MediaLiveのChannel作成
配信チャンネルを作成します。(これが中々大変です。。)
Create channel
でChannel作成画面を開きます。

Channel and input details
General info
Channel名とIAMロールを設定します。

Channel template
既存のテンプレートであるLive event
(HLSの方)を設定します。

すると、Output groupsにHLS形式の出力設定が追加されます。
Channel class
ここはSINGLE_PIPELINE
を設定します。
デフォルト設定であるSTANDARD
を使うと、Multi-AZで構成される2つのパイプラインを使用した冗長構成になりますが、Multi-AZ構成でない場合や検証の場合等には、SINGLE_PIPELINE
を使った方が安価に使えます。

Input Attachments
ADD
を押して、プルダウンからChannelに紐づけるinputを選択し、Confirm
を押します。

今回のケースだと、予告動画と終了後動画はループ再生させたいので、作成したInput Attachmentsを選択してSource End Behavior
をLOOP
に変更します。

Output groups
作成したMediaStoreのコンテナを、配信先に設定します。
URL
ここのURLには、MediaStoreのコンテナに記載されているData endpoint
を記載しますが、httpsをmediastoresslに置き換える必要があるので、ご注意ください。
配信先にしたいMediaStoreのEndpointが下記のような場合、
https://XXXXXXXXXXXXXX.data.mediastore.ap-northeast-1.amazonaws.com/<path>/<basename>
URLには以下のように設定します。
mediastoressl://XXXXXXXXXXXXXX.data.mediastore.ap-northeast-1.amazonaws.com/<path>/<basename>
<path>
にはコンテナ以下のパス、<basename>
には設定したいマニフェストファイル名を入れます。
(OutputにName Modifierを設定した場合は、<basename>
にName Modifierを結合した名前がマニフェストファイル名になります)
CDN Settings
今回はMediaStoreを配信先に指定しているので、Hls media store
を設定してください。

出力される映像の画角やビットレート、コーデック等についてはOutputごとに設定できるので、その辺りを調整する場合はそちらで行ってください。
Create Channel
ここまで設定が終わったら、Create channel
を押します。
Schedule設定
最後に、配信スケジュールを作成します。
ChannelのScheduleタブを開き、Create
します。

2019/12/8 22:00になったら本編に切り替える
Action nameに適当な名前を入力します。
Start typeをFixed
に指定し、Date、Timeを2019/12/8 13:00に設定します。(TimeはUTCなので注意)
次に、Action typeをInput Switch
に、Input attachmentで本編であるmain
を設定し、Create
します。

これで、2019/12/8 22:00(JST)になったら本編に切り替わるようになります。
本編が終了したら終了後動画に切り替える
Action nameに適当な名前を入力後、こちらではStart typeをFollow
に指定します。
Reference action nameに上記で作成したスケジュール名を指定し、Follow pointをEND
に設定します。
Action typeはinput Switch
で、Input attachmentはfinished
を設定し、Create
します。

この設定で、本編が終了したら終了後動画に切り替わるようになります。
設定完了
上記の設定ができたら、Scheduleタブにはこのように表示されます。

【注意】ChannelがRUNNINGじゃないとスケジュール機能は動作しない
若干ハマったポイントなんですが、スケジュール機能はChannelがRUNNING状態になっていないと動作しません。
設定したスケジュール日時になる前に必ずRUNNINGにしておきましょう。
(Scheduleを設定したから時間通り動くでしょとか思っていたら動きませんでした)
本当はChannelの起動もMediaLive内でできたらいいなとか思っているのですが、そのような機能はなさそう。
そこも自動化したければ、Lambda等と連携する必要がありそうです。
おわりに
これで全ての設定が完了です。お疲れ様でした。
ChannelをStart
させれば予告動画が配信され、スケジュール設定した時刻になれば本編が流れます。
今回はMediaLiveを使ってスケジュールした時間に予告→本編→終了後と切り替わる配信を試してみました。
ちょっとChannelの設定を作るのは大変ですが、これだけでスケジュール管理された動画配信ができるのはすごいですよね。
とはいえ、この操作を毎度コンソールから行うのは手間がかかり過ぎてしまうので、現実的にはSDKを使って自動で設定が作られるようにすべきだろうなとは思います。
参考記事
https://qiita.com/khagi/items/ff8120c498a7d45338b1
https://dev.classmethod.jp/cloud/aws/aws-elemental-medialive-programming-using-mp4-input-and-switch-input/
https://qiita.com/ryotax/items/60f7ec699cfaec62a8be