我们在 iOS 8.4 上使用 AVPlayer 来播放 HLS、AES 加密的视频。
我们的 .m3u8 文件包含许可证服务器的 url,例如:
EXT-X-KEY:METHOD=AES-128,URI="https://...."
在我们的 iOS 应用程序中,我们使用 AVAssetResourceLoaderDelegate 方法 资源加载器:shouldWaitForLoadingOfRequestedResource: 拦截由 AVPlayer(或 AVFoundation 中的某个对象)发送到许可服务器的请求。在该方法中,我们将 token (许可服务器需要)添加到请求的 queryString。
许可证服务器接收带有 token 的请求,返回加密 key ,然后开始播放。 换句话说,一切都按预期工作。
但是,我们注意到(使用“Charles”http 监视器)在创建 AVPlayerItem 之后和调用 resourceLoader: 方法之前,AVFoundation 发送一个初始请求许可证服务器 url;未通过方法 resourceLoader:“路由”的请求。该请求在服务器上被拒绝,因为我们的 iOS 代码从来没有机会在请求发出之前附加 token 。
事件总结:
• 使用 .m3u8 索引文件的 url 创建并初始化 AVPlayerItem/AVAsset。
• AVFoundation 框架中的某些内容向.m3u8 文件中指定的许可服务器发出请求。此初始请求未被方法 recourceLoader:shouldWaitForLoadingOfRequestedResource: 拦截,并且未修改的请求到达许可服务器。因为请求在 queryString 中不包含必需的 token ,所以它失败并且没有返回加密 key 。
• AVFoundation 向许可服务器发出第二个请求。此请求被 recourceLoader 捕获:...并进行了适当的修改。许可服务器返回加密 key 并开始播放。
可以使用 Apple 的 AVARLDelegateDemo 应用复制此行为。
问题:
AVFoundation发送的初始http请求是否正常?
如果是这样,为什么有必要,为什么不通过 resourceLoader: 方法“路由”它?
是否可以在发送前抑制初始请求或修改它?
谢谢!
最佳答案
这个问题的简单答案是 AVAssetResourceLoaderDelegate
将只处理无法以正常方式处理的 URL 请求。
在您的情况下, key 的 URL 是一个普通的 https://URL,因此 AVPlayer 将尝试自行处理此请求。但是,如果没有 token ,您的服务器会拒绝此请求。因此,AVAssetResourceLoaderDelegate
会将请求传递给您的委托(delegate)来处理它。
为避免“无关”请求,请修改您的播放列表,使加密 key URL 具有无效方案。使用类似于 crypt://... 而不是 https://....
这样,您将在第一次尝试时收到资源加载器调用,您可以将 crypt://方案替换为 https://并在以正常方式自行发出请求之前添加您的 token 。
恐怕这就是 AVAssetResourceLoaderDelegate
的工作方式。
在此处查看 Apple 的示例应用程序以获取更多详细信息:
https://developer.apple.com/library/ios/samplecode/sc1791/
关于ios - AVPlayer 在播放 HLS/AES 加密视频之前发出无关的 http 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31727139/