【やってみた】AWS Media Servicesを使ったHLSライブストリーミングの配信部分にAmazon CloudFrontを使ってみた #reinvent

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

清水です。AWS Media Servicesを使ったライブ配信ではAWS Elemental MediaLiveとAWS Elemental MediaPackageを使用します。先日やってみたこちらのエントリではAWS Elemental MediaPackageのEndpointのURLを参照してHLS形式でのライブストリーミングを確認できました。しかしre:Invent2017のブレイクアウトセッション「CTD204 - NEW LAUNCH! Hear how the Pac-12 is using AWS Elemental MediaStore and explore video workflows with MediaLive and MediaPackage」などではAWS Elemental MediaPackageと実際の配信ユーザや配信デバイスの間にAmazon CloudFront(またはCDN)を導入する構成となっています。あくまでMediaPackageは配信サービスのオリジンであり、効率的な配信を行うにはAmazon CloudFrontなどCDNを活用したほうがよさそうです。本エントリではAWS Elemental MediaPackageをオリジンとしてAmazon CloudFrontディストリビューションを設定し、HLS形式によるライブストリーミングをしてみたのでまとめてみます。

やってみた

CloudFrontの設定

MediaServices側の設定としては、以下のエントリのようにAWS Elemental MediaLiveとAWS Elemental MediaPackageを構成します。この時点でMediaPackageのEndpointのURLからライブストリーミングがHLS形式で参照可能となっている、とします。

このMediaPackageのHLS形式のEndpointですが、以下の形式になります。

  • https://[16桁の英数字].mediapackage.us-west-2.amazonaws.com/out/v1/[32桁の英数字]/index.m3u8

オリジンのドメインとしてはこの[16桁の英数字].mediapackage.us-west-2.amazonaws.comとなるので、CloudFrontのオリジンのドメイン名にこの値を指定すればよさそうですね。設定にあたり注意した点を以下にまとめてみます。

オリジンへのアクセスはHTTPSのみ

オリジンとなるMediaPackageのEndpointですが、httpsではじまっています。試しにHTTPでアクセスしてみましたが、応答はありませんでした。HTTPSのみの対応となっているようです。

$ curl -I https://[16桁の英数字].mediapackage.us-west-2.amazonaws.com/out/v1/[32桁の英数字]/index.m3u8
HTTP/1.1 200 OK
Date: Mon, 11 Dec 2017 09:29:58 GMT
Content-Type: application/x-mpegURL
Content-Length: 424
Connection: keep-alive
Server: AWS Elemental MediaPackage
Access-Control-Allow-Headers: origin, x-requested-with, content-type, range
Access-Control-Allow-Methods: GET,HEAD,OPTIONS
Access-Control-Allow-Origin: *
Cache-Control: max-age=2
X-MediaPackage-Cache-Status: MISS
X-MediaPackage-Request-Id: e96acf956f6eade96a69781c113aeb4d

$ curl -I http://[16桁の英数字].mediapackage.us-west-2.amazonaws.com/out/v1/[32桁の英数字]/index.m3u8
curl: (52) Empty reply from server

そのため、CloudFrontからオリジンの通信についてもHTTPSのみとしておきます。Origin Protocol Policyの箇所でHTTPS Onlyを選択します。

キャッシュの設定

キャッシュまわりの設定についても確認しておきます。HLSライブストリーミングでは特にマニフェストファイル(m3u8)は常に更新されることが前提なので、24時間キャッシュされる、なんて設定ではライブとして成立しなくなりますね。まずはオリジンであるMediaPackageのキャッシュ設定をみてみます。

$ curl -I https://[16桁の英数字].mediapackage.us-west-2.amazonaws.com/out/v1/[32桁の英数字]/index.m3u8
HTTP/1.1 200 OK
Date: Tue, 12 Dec 2017 10:16:23 GMT
Content-Type: application/x-mpegURL
Content-Length: 424
Connection: keep-alive
Server: AWS Elemental MediaPackage
Access-Control-Allow-Headers: origin, x-requested-with, content-type, range
Access-Control-Allow-Methods: GET,HEAD,OPTIONS
Access-Control-Allow-Origin: *
Cache-Control: max-age=2
X-MediaPackage-Cache-Status: EXPIRED
X-MediaPackage-Request-Id: da1263ee5956092b5d49488d1b1a086c

$ curl -I https://[16桁の英数字].mediapackage.us-west-2.amazonaws.com/out/v1/[32桁の英数字]/index_1.m3u8
HTTP/1.1 200 OK
Date: Tue, 12 Dec 2017 10:16:30 GMT
Content-Type: application/x-mpegURL
Content-Length: 516
Connection: keep-alive
Server: AWS Elemental MediaPackage
Access-Control-Allow-Headers: origin, x-requested-with, content-type, range
Access-Control-Allow-Methods: GET,HEAD,OPTIONS
Access-Control-Allow-Origin: *
Cache-Control: max-age=2
X-MediaPackage-Cache-Status: EXPIRED
X-MediaPackage-Request-Id: 1f83775763e8c951bb28e76744781cdc

$ curl -I https://[16桁の英数字].mediapackage.us-west-2.amazonaws.com/out/v1/[32桁の英数字]/index_1_4708.ts?m=1512981548
HTTP/1.1 200 OK
Date: Tue, 12 Dec 2017 10:16:49 GMT
Content-Type: video/MP2T
Content-Length: 3892540
Connection: keep-alive
Server: AWS Elemental MediaPackage
Access-Control-Allow-Headers: origin, x-requested-with, content-type, range
Access-Control-Allow-Methods: GET,HEAD,OPTIONS
Access-Control-Allow-Origin: *
Cache-Control: max-age=21600
X-MediaPackage-Cache-Status: MISS
X-MediaPackage-Request-Id: b619345af2fa8f6c4334c38b62fe88b1

マニフェストファイル(m3u8)についてはCache-Controlヘッダでmax-age=2の値がついています。またセグメントファイル(ts)については同じくCache-Controlヘッダでmax-age=21600の値がついていることが確認できました。CloudFront側のキャッシュの設定としてはオリジン側の設定をそのまま使う(Use Origin Cache Headers)、またはBehaviorで *.m3u8 は2秒、 *.ts については21600秒のキャッシュを行う設定とすればよさそうです。

以下はBehaviorで各拡張子ごとにキャッシュ期間を設定した例となります。こちらのエントリを参考に3つのTTL設定はすべて同じ値にしました。

その他

他にCloudFront側で設定しておいたほうがよい事項として、CloudFrontのアクセスログが挙げられるかと思います。配信と直接的な関係はないと言えばないのですが、CloudFront側でアクセスログを有効にしておけば、何かあった場合の調査やCloudFrontの各種アクセス分析レポート以上の解析を行いたい場合に活用できるかと思います。

また、CloudFrontディストリビューションのドメインはd[ランダムな英数字].clodfront.netという形式ですが、必要に応じてCNAMEを設定、独自ドメインを使用するのも良いかと思います。

CloudFront経由での配信の確認

CloudFrontディストリビューションを設定し、StateがEnabledになった配信の確認をしてみます。マニフェストファイルへのアドレスはMediaPackageのEndpointである以下の形式から、

  • https://[16桁の英数字].mediapackage.us-west-2.amazonaws.com/out/v1/[32桁の英数字]/index.m3u8

ドメイン部分が変わり、以下となります。

  • https://d[ランダムな英数字].cloudfront.net(CloudFrontのDomain Name)/out/v1/[32桁の英数字]/index.m3u8

こちらのマニフェストファイルへアクセスすると、MediaPackageにアクセスしていたときと同様、ライブストリーミングが視聴できます。

またヘッダ情報等確認してみると以下のようでした。

$ curl -I https://d[ランダムな英数字].cloudfront.net/out/v1/[32桁の英数字]/index.m3u8
HTTP/1.1 200 OK
Content-Type: application/x-mpegURL
Content-Length: 424
Connection: keep-alive
Date: Tue, 12 Dec 2017 11:20:25 GMT
Server: AWS Elemental MediaPackage
Access-Control-Allow-Headers: origin, x-requested-with, content-type, range
Access-Control-Allow-Methods: GET,HEAD,OPTIONS
Access-Control-Allow-Origin: *
Cache-Control: max-age=2
X-MediaPackage-Cache-Status: EXPIRED
X-MediaPackage-Request-Id: d57db70ca396c7199b7d36d6ab1c1f2e
X-Cache: Miss from cloudfront
Via: 1.1 2fe788985cac89c0ef661ff7cd8edf63.cloudfront.net (CloudFront)
X-Amz-Cf-Id: WefOayl7_g_j_jeyqocZK7FwIahSIEqRu7nD2nED4vXDXr56xFiI6A==


$ curl -I https://d[ランダムな英数字].cloudfront.net/out/v1/[32桁の英数字]/index_1.m3u8
HTTP/1.1 200 OK
Content-Type: application/x-mpegURL
Content-Length: 516
Connection: keep-alive
Date: Tue, 12 Dec 2017 11:20:29 GMT
Server: AWS Elemental MediaPackage
Access-Control-Allow-Headers: origin, x-requested-with, content-type, range
Access-Control-Allow-Methods: GET,HEAD,OPTIONS
Access-Control-Allow-Origin: *
Cache-Control: max-age=2
X-MediaPackage-Cache-Status: EXPIRED
X-MediaPackage-Request-Id: d965a9af69e1e0be5b49927a28375cdd
X-Cache: Miss from cloudfront
Via: 1.1 2c6248542582010bc022ce33969f1509.cloudfront.net (CloudFront)
X-Amz-Cf-Id: X3GCGOxfkGGsIWnWJfLicChEwWXNda3T3L7GAl2oDSPzmifPRS7OpQ==


$ curl -I https://d[ランダムな英数字].cloudfront.net/out/v1/[32桁の英数字]/index_1_5348.ts?m=1512981548
HTTP/1.1 200 OK
Content-Type: video/MP2T
Content-Length: 4011920
Connection: keep-alive
Date: Tue, 12 Dec 2017 11:20:43 GMT
Server: AWS Elemental MediaPackage
Access-Control-Allow-Headers: origin, x-requested-with, content-type, range
Access-Control-Allow-Methods: GET,HEAD,OPTIONS
Access-Control-Allow-Origin: *
Cache-Control: max-age=21600
X-MediaPackage-Cache-Status: MISS
X-MediaPackage-Request-Id: b365fa258e50c570576dbbcb1c99fd13
X-Cache: Miss from cloudfront
Via: 1.1 608d91b2056eb3f144195eeb296801c4.cloudfront.net (CloudFront)
X-Amz-Cf-Id: lDxMRpP0WODw7HIxffLbTTXuaGDLZoDLucbUN9tNLVTXV8c_rvh9sQ==


$ curl -I https://d[ランダムな英数字].cloudfront.net/out/v1/[32桁の英数字]/index_1_5348.ts?m=1512981548
HTTP/1.1 200 OK
Content-Type: video/MP2T
Content-Length: 4011920
Connection: keep-alive
Date: Tue, 12 Dec 2017 11:20:43 GMT
Server: AWS Elemental MediaPackage
Access-Control-Allow-Headers: origin, x-requested-with, content-type, range
Access-Control-Allow-Methods: GET,HEAD,OPTIONS
Access-Control-Allow-Origin: *
Cache-Control: max-age=21600
X-MediaPackage-Cache-Status: MISS
X-MediaPackage-Request-Id: b365fa258e50c570576dbbcb1c99fd13
Age: 1
X-Cache: Hit from cloudfront
Via: 1.1 cd173f10bb7757a5043f61f030d6f707.cloudfront.net (CloudFront)
X-Amz-Cf-Id: lkfpjk9HaVobISbI9FIb2SWhZdoame6uy9tk-EcPGcTp_VyvJXToFg==

まとめ

AWS Elemental MediaLiveとAWS Elemental MediaPackageから構成されるHLSライブストリーミング環境に対して、配信部分にAmazon CloudFrontを導入してみました。オリジンとなるMediaPackageのEndpointへのアクセスがHTTPSのみとなる点については注意が必要ですが、その他の項目については特別な設定をしなくても配信ができました。キャッシュまわりについても確認は行いましたが、デフォルト設定であるUse Origin Cache Headersの設定でも配信ができるよう設定されているようです。 また現状MediaPackageについてはテキストベースのログ出力機能などが確認できておらずCloudWatchメトリクスのみでのモニタリングとなるので、アクセスログを活用したいような場合はAmazon CloudFrontの導入で対応できそうです。また何より容易にAmazon CloudFrontによる大規模配信、高速配信が可能になる点は大きいのではないでしょうか。