#はじめに
もう数か月経ちますが、AzureメディアサービスのDynamic PackagingがAppleのFairPlay Streamingに対応しました。
Azure Media Services 向け Apple FairPlay Streaming の一般提供を開始
一般提供の開始当初は、AzureメディアサービスではHLSに対して、1つの暗号化方式しか設定できないという制約がありましたが、現在は以下3つの暗号化形式を同時に設定できるようになりました。
- AES-128 エンベロープ クリア キー
- Apple FairPlay (Streaming)
- Microsoft PlayReady
例えば、既にAndroid/iOS向けにHLS×PlayReadyを配信中のアセットに対して、新たにMacのSafari向けにHLS×FairPlay Streamingを提供するということができるようになりました。
Apple FairPlay または Microsoft PlayReady による HLS コンテンツの保護
やってみた
先ほどのリンクを参考に
暗号化方式 | 設定 |
---|---|
PlayReady | 設定する |
FairPlay Streaming | 設定する |
AES-128 | 設定しない |
といった感じに、アセットに対してFPSとPlayReadyを設定した場合を試してみました。
ダメだった
さきほどのリンク先のストリーミングURLの章の通りに各暗号化方式のURLを作ると
それぞれの暗号化URLは以下のようになります。
暗号化方式 | URL |
---|---|
PlayReady | http://{アカウント名}.streaming.mediaservices.windows.net/{ロケータID}/{マニフェスト名}.ism/manifest(format='m3u8-aapl',encryption='cenc') |
FairPlay Streaming | http://{アカウント名}.streaming.mediaservices.windows.net/{ロケータID}/{マニフェスト名}.ism/manifest(format='m3u8-aapl',encryption='cbcs-aapl') |
AES-128 | http://{アカウント名}.streaming.mediaservices.windows.net/{ロケータID}/{マニフェスト名}.ism/manifest(format='m3u8-aapl',encryption='cbc') |
しかし、これらのURLにリクエストすると415 Unsupported Media Typeのレスポンスが返ってきます。
GET http://xxx.streaming.mediaservices.windows.net/xxx/xxx.ism/manifest(format='m3u8-aapl',encryption='cenc') HTTP/1.1
User-Agent: Fiddler
Host: xxx.streaming.mediaservices.windows.net
HTTP/1.1 415 Unsupported Media Type
Content-Type: text/xml
Server: Microsoft-IIS/8.5
x-ms-streaming-duration: 0
X-Powered-By: ASP.NET
X-Content-Type-Options: nosniff
Access-Control-Allow-Origin: *
Date: Wed, 07 Dec 2016 15:54:52 GMT
Content-Length: 279
英語の原文を読んでも、URLの末尾に付いているformatやencryptionパラメータの値がアポストロフィー「'」で囲まれているのですが、実はこれが必要ありません。
できた
アポストロフィーを抜いた正しいリクエストURLは以下の通りです。
暗号化方式 | URL |
---|---|
PlayReady | http://{アカウント名}.streaming.mediaservices.windows.net/{ロケータID}/{マニフェスト名}.ism/manifest(format=m3u8-aapl,encryption=cenc) |
FairPlay Streaming | http://{アカウント名}.streaming.mediaservices.windows.net/{ロケータID}/{マニフェスト名}.ism/manifest(format=m3u8-aapl,encryption=cbcs-aapl) |
AES-128 | http://{アカウント名}.streaming.mediaservices.windows.net/{ロケータID}/{マニフェスト名}.ism/manifest(format=m3u8-aapl,encryption=cbc) |
正常系
今回、PlayReadyとFairPlay Streamingのみセットしているので、この2つは200 OKが返ってきます。
GET http://xxx.streaming.mediaservices.windows.net/xxx/xxx.ism/manifest(format=m3u8-aapl,encryption=cenc) HTTP/1.1
User-Agent: Fiddler
Host: xxx.streaming.mediaservices.windows.net
HTTP/1.1 200 OK
Cache-Control: max-age=604800
Pragma: IISMS/6.0,IIS Media Services Premium by Microsoft
Content-Length: 2489
Content-Type: application/vnd.apple.mpegurl
Expires: Wed, 14 Dec 2016 16:05:30 GMT
Server: Microsoft-IIS/8.5 IISMS/6.0
x-ms-streaming-duration: 0
X-Powered-By: ASP.NET
X-Content-Type-Options: nosniff
Access-Control-Allow-Origin: *
Date: Wed, 07 Dec 2016 16:05:29 GMT
GET http://xxx.streaming.mediaservices.windows.net/xxx/xxx.ism/manifest(format=m3u8-aapl,encryption=cbcs-aapl) HTTP/1.1
User-Agent: Fiddler
Host: xxx.streaming.mediaservices.windows.net
HTTP/1.1 200 OK
Cache-Control: max-age=604800
Pragma: IISMS/6.0,IIS Media Services Premium by Microsoft
Content-Length: 1416
Content-Type: application/vnd.apple.mpegurl
Expires: Wed, 14 Dec 2016 16:13:33 GMT
Server: Microsoft-IIS/8.5 IISMS/6.0
x-ms-streaming-duration: 0
X-Powered-By: ASP.NET
X-Content-Type-Options: nosniff
Access-Control-Allow-Origin: *
Date: Wed, 07 Dec 2016 16:13:33 GMT
ヘッダだけだと区別がつきませんが、ボディのプレイリストを見るとそれぞれPlayReadyとFPSが返ってきていることが分かります。
異常系
前述のように、AES-128は設定していないのに出力されてないか確認します。特にAES-128だと暗号化キーは特に保護されていないので、勝手にストリーム可能な状態になっていたら大変です。
リクエストしてみると、設定していない暗号化方式は403 Forbiddenになることが確認できます。
GET http://xxx.streaming.mediaservices.windows.net/xxx/xxx.ism/manifest(format=m3u8-aapl,encryption=cbc) HTTP/1.1
User-Agent: Fiddler
Host: xxx.streaming.mediaservices.windows.net
HTTP/1.1 403 Forbidden
Content-Type: text/xml
Server: Microsoft-IIS/8.5
x-ms-streaming-duration: 0
X-Powered-By: ASP.NET
X-Content-Type-Options: nosniff
Access-Control-Allow-Origin: *
Date: Wed, 07 Dec 2016 16:19:00 GMT
Content-Length: 293
レスポンスのXMLをフォーマットするとこんな風になっていて、hresultからもDeliveryPolicyに設定していない暗号化方式を指定したことがエラーの原因であることが確認できます。
<?xml version="1.0" encoding="utf-8"?>
<serverError>
<status>403</status>
<subStatus>0</subStatus>
<hresult>MPE_ENC_ENCRYPTION_NOT_SET_IN_DELIVERY_POLICY</hresult>
<activityId>(省略)</activityId>
<serviceId>(省略)</serviceId>
</serverError>
また、暗号化方式を2つ以上設定しているときは、encryptionパラメータは省略できないので、もし省略してリクエストすると、400 Bad Requestになります。
GET http://xxx.streaming.mediaservices.windows.net/xxx/xxx.ism/manifest(format=m3u8-aapl) HTTP/1.1
User-Agent: Fiddler
Host: xxx.streaming.mediaservices.windows.net
HTTP/1.1 400 Bad Request
Content-Type: text/xml
Server: Microsoft-IIS/8.5
x-ms-streaming-duration: 0
X-Powered-By: ASP.NET
X-Content-Type-Options: nosniff
Access-Control-Allow-Origin: *
Date: Wed, 07 Dec 2016 16:23:31 GMT
Content-Length: 287
<?xml version="1.0" encoding="utf-8"?>
<serverError>
<status>400</status>
<subStatus>0</subStatus>
<hresult>MPE_ENC_ENCRYPTION_NOT_SPECIFIED_IN_URL</hresult>
<activityId>(省略)</activityId>
<serviceId>(省略)</serviceId>
</serverError>
ちなみに、暗号化方式を1つしか指定していない場合は、従来通りencryptionパラメータなしでも200 OKが返ってきます。
まとめ
というわけで、SafariでSilverlightがデフォルト無効になってしまったし、そろそろHTML5プレイヤーに移行しないとまずいかなという場合でもAzureメディアサービスを使えば簡単にFairPlay Streaming対応できちゃう!
・・・といいですね。
(実際には色々と制約があって、考慮しなければいけないことも多いです。)
※一部の値を伏字(xxx)や「省略」に書き換えています