1. m-otoguro

    Posted

    m-otoguro
Changes in title
+Azureメディアサービス:HLSを複数の暗号化形式で配信する
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,195 @@
+#はじめに
+
+もう数か月経ちますが、AzureメディアサービスのDynamic PackagingがFairPlay Streamingに対応しました。
+
+[Azure Media Services 向け Apple FairPlay Streaming の一般提供を開始](https://blogs.msdn.microsoft.com/devamm/2016/09/09/azure-media-services-%e5%90%91%e3%81%91-apple-fairplay-streaming-%e3%81%ae%e4%b8%80%e8%88%ac%e6%8f%90%e4%be%9b%e3%82%92%e9%96%8b%e5%a7%8b/)
+
+一般提供の開始当初は、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 コンテンツの保護](https://docs.microsoft.com/ja-jp/azure/media-services/media-services-protect-hls-with-fairplay)
+
+# やってみた
+
+先ほどのリンクを参考に
+
+|暗号化方式 | 設定 |
+|:-------- |:------|
+|PlayReady | 設定する |
+|FairPlay Streaming | 設定する |
+|AES-128 | 設定しない |
+
+といった感じに、アセットに対してFPSとPlayReadyを設定した場合を試してみました。
+
+# ダメだった
+
+さきほどのリンク先の[ストリーミングURL](https://docs.microsoft.com/ja-jp/azure/media-services/media-services-protect-hls-with-fairplay#a-namestreaming-urlsaストリーミング-url)の章の通りに各暗号化方式のURLを作ると
+それぞれの暗号化URLは以下のようになります。
+
+|暗号化方式 | URL |
+|:-------- |:------|
+|PlayReady | http://{アカウント名}.streaming.mediaservices.windows.net/{ロケータID}/{マニフェスト名}.ism/manifest(<strong>format='m3u8-aapl',encryption='cenc'</strong>) |
+|FairPlay Streaming | http://{アカウント名}.streaming.mediaservices.windows.net/{ロケータID}/{マニフェスト名}.ism/manifest(<strong>format='m3u8-aapl',encryption='cbcs-aapl'</strong>) |
+|AES-128 | http://{アカウント名}.streaming.mediaservices.windows.net/{ロケータID}/{マニフェスト名}.ism/manifest(<strong>format='m3u8-aapl',encryption='cbc'</strong>) |
+
+しかし、これらのURLにリクエストすると415 Unsupported Media Typeのレスポンスが返ってきます。
+
+```http:アポストロフィー付:リクエスト
+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:アポストロフィー付:レスポンスヘッダ
+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(<strong>format=m3u8-aapl,encryption=cenc</strong>) |
+|FairPlay Streaming | http://{アカウント名}.streaming.mediaservices.windows.net/{ロケータID}/{マニフェスト名}.ism/manifest(<strong>format=m3u8-aapl,encryption=cbcs-aapl</strong>) |
+|AES-128 | http://{アカウント名}.streaming.mediaservices.windows.net/{ロケータID}/{マニフェスト名}.ism/manifest(<strong>format=m3u8-aapl,encryption=cbc</strong>) |
+
+## 正常系
+
+今回、PlayReadyとFairPlay Streamingのみセットしているので、この2つは200 OKが返ってきます。
+
+```http:PlayReady:リクエスト
+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:PlayReady:レスポンスヘッダ
+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
+```
+
+```http:FairPlayStreaming:リクエスト
+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:FairPlayStreaming:レスポンスヘッダ
+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になることが確認できます。
+
+```http:AES-128:リクエスト
+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:AES-128:レスポンスヘッダ
+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:AES-128:レスポンスボディ
+<?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になります。
+
+```http:encryption未指定:リクエスト
+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:encryption未指定:レスポンスヘッダ
+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:encryption未指定:レスポンスボディ
+<?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)や「省略」に書き換えています