用AirPlay 2播放AES加密影片的坑

TL; DR

如果在透过Airplay 2播放AES加密影片的时候,发现无法正确的呼叫到实作的AVAssetResourceLoaderDelegate,以至于没有正确加入授权(存取凭证)而无法下载影片播放时,只需重新读取的HLS影片来源URL scheme客制化即可。

前言

为了防止正版影片被盗用,影片在传输前就会先加密好,才传送给使用者端解密,观看。常用的保护方式如透过数位版权管理(DRM),或依据进阶加密标准(高级加密标准,AES)加密,而这篇文章就是谈谈在客户端AES解密影片时用AirPlay2投影所遇到的坑!

使用AVAssetResourceLoaderDelegate

AVAssetResourceLoaderDelegate(后面简化成“ ARL委托”)是Apple的AVKit中读取到AVURLAsset资源时,通知应用程序端处理的委派模式(代理模式)。理论上,当AVKit需要您的应用程序“植入”去读取资源(影片,m3u8档案或字幕档案)时,就会去呼叫resourceLoader(_:shouldWaitForLoadingOfRequestedResource :),这时候app就可以加入读取所需的授权验证(例如:auth token),来让你的服务端能够验证您的资源读取需求,并回传你所需要的资源档案。

替换成客制化方案的流程:

读取master播放列表(master.m3u8)

让一开始读取的master.m3u8 URL方案在应用端从https cplpcplphttps://example.com/master.m3u8 –> cplp ://example.com/master.m3u8),而因为这个客制化的cplp URL方案,就会让ARL委托被触发,并通过resourceLoader(_:shouldWaitForLoadingOfRequestedResource :)能够被顺利的调用到,但这里只需要去获得master.m3u8档案并回传给loadingRequest即可,不需要其他的处理。

注意:若不确定原始先使用的协议会是 http https 的话,可以通过“加入前缀”的方式去改成客制化sheme,例如在scheme前面加上 my ,则 http 就会变成 myhttp ,而 https 就会变成 myhttps 。如此一来,想要还原原本的方案,只需要可移除的前缀即可。

读取index播放列表(index.m3u8)

因为master.m3u8的URL被窜改成客制化的URL方案,所以一来根据HLS(http live stream)的规则,master中的index.m3u8连结也就会自动变成cplp://example.com/index .m3u8,并且成功让ARL代表也被呼叫。

但因为密钥将链接放置在index.m3u8的缘故,则​​需要更进一步的将成为“#EXT-X-KEY:METHOD = AES-128,URI =” https://example.com/key “”给换成“#EXT-X-KEY:METHOD = AES-128,URI =” ckey ://example.com/key””(注意这里的自定义方案“ ckey”特别与m3u8有所改善的区隔)。换完之后再转回数据传回给loadingRequest

读取影片解密金钥

被替换成客制化scheme的金钥连结(ckey://example.com/key)一样会呼叫ARL代表,并且可以依据“ ckey” scheme来识别出目前处理的资源是“取得影片解密金钥” ,因此在对连结发出request的时候,就可以额外加入auth token来让服务端验证

取得其他相关资源

在index播放列表中,有可能会包含其他的影片资源需要读取,包含字幕档案,广告或者影片档案,这时候除了恢复URL计划回https后,直接获取连结档案内容回传以外,还可以以http状态码“ 302”的方式将它“ redirect”回去,而不用直接处理「取得档案内容」这样琐碎的事情

总结

如果没有特殊验证凭证的需求,个人比较偏好使用Cookie的方式传递授权验证,但如果有像我一样有开发上的限制或困难的话,可以考虑看看这样的解密流程啰!

参考

  • AirPlay概述-加密密钥下载的身份验证
  • AVARLDelegateDemo