MPEG DASHを使ってアダプティブストリーミングで動画を配信しようと挑戦したところ,CORSで躓いたのでまとめます.
目標
shaka-playerを使ってDASHでアダプティブストリーミングする.
動画を配信するためにAmazon S3を使い,CloudFrontでキャッシュする.
問題点
動画を貼り付けるWebサイトは,動画を配信するCloudFrontとは別のオリジンなので,オリジン間リソース共有 (CORS)に対応する必要があります.
shaka-playerのリスクエスト
以下のshaka-playerのデモで,どのようなリクエストが行われるかを確認します.
最初にdash.mpdを読み込みます.内容の一部は以下のようになります.
<?xml version="1.0" encoding="UTF-8"?> <!--Generated with https://github.com/google/shaka-packager version v2.4.1-c731217-release--> <MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT60S"> <Period id="0"> ... <AdaptationSet id="6" contentType="video" maxWidth="720" maxHeight="576" frameRate="12800/512" par="5:4"> <Representation id="6" bandwidth="492476" codecs="avc1.4d400d" mimeType="video/mp4" sar="1:1" width="300" height="240"> <BaseURL>video_240p_242k_h264.mp4</BaseURL> <SegmentBase indexRange="860-1071" timescale="12800"> <Initialization range="0-859"/> </SegmentBase> </Representation> <Representation id="7" bandwidth="991296" codecs="avc1.4d4015" mimeType="video/mp4" sar="1:1" width="450" height="360"> <BaseURL>video_360p_400k_h264.mp4</BaseURL> <SegmentBase indexRange="862-1073" timescale="12800"> <Initialization range="0-861"/> </SegmentBase> </Representation> <Representation id="12" bandwidth="162364" codecs="avc1.4d400c" mimeType="video/mp4" sar="1:1" width="180" height="144"> <BaseURL>video_144p_108k_h264.mp4</BaseURL> <SegmentBase indexRange="860-1071" timescale="12800"> <Initialization range="0-859"/> </SegmentBase> </Representation> ... </AdaptationSet> </Period> </MPD>
アダプティブストリーミングでは,解像度が異なる複数の動画ファイルを用意し,ネットワーク回線の状態に応じて,shaka-playerがどのファイルを再生するのかを切り替える仕組みです.
Chromeのインスペクタでネットワークを確認します.
このように,1つの動画ファイルをそのままダウンロードするのではなく,Rangeヘッダーを使って,動画ファイルを少しずつダウンロードします.
これらの動作により,必要なデータのみをダウンロードすることができるので,動画配信にかかるコストを減らすことができます.
CORSの設定
CORSでは,origin, method, headerの全てが許可されなければいけません.上記の配信において,Rangeヘッダーを許可しなければなりません.Amazon S3のCORS configurationで以下の設定をします.
<?xml version="1.0" encoding="UTF-8"?> <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <CORSRule> <AllowedOrigin>*</AllowedOrigin> <AllowedMethod>HEAD</AllowedMethod> <AllowedMethod>GET</AllowedMethod> <AllowedHeader>range</AllowedHeader> </CORSRule> </CORSConfiguration>
CloudFrontで,rangeヘッダーを含めてCORSに対応できるように設定します.DistributionsのBehavioursの編集画面を開きます.
まず,Allowed HTTP Methods を,GET, HEAD, OPTIONS にします.preflightリクエストのCORSに対応するために,OPTIONSを明示的に許可しなければなりません.
Cache Based on Selected Request Headers を,Whitelistにします.そして,Whitelist Headersに,
- Access-Control-Request-Headers
- Access-Control-Request-Method
- Origin
- Range
の4個を追加します.これにより,shaka-playerがCloudFrontにリクエストを送信すると,S3にもこれらのヘッダーが送信され,CORSの設定が有効となります.
以上で,CORSが正しく適応されるようになりました.