是否可以使用AVPlayer缓存HLS段?

时间:2015-04-03 15:03:10

标签: ios video-streaming avfoundation avplayer http-live-streaming

根问题

在iOS中搜索时,我们的视频会缓冲很多。它比我们的网络播放器缓存了更多,它将已经监视的片段的副本保存在临时存储器中。

所需解决方案

在设备的磁盘上本地缓存视频片段。我们可以通过缓存单一质量并且始终重播它。

阻断剂

我们无法找到在AVFoundation / AVPlayer中执行缓存的方法。

我们尝试过什么

使用AVPlayer拦截网络请求的两种方法。

  1. 符合AVAssetResourceLoaderDelegate并手动处理媒体加载
  2. 不适用于HLS。您可以通过实现AVAssetResourceLoaderDelegate来加载m3u8文件,它允许您通过身份验证或解密响应,但无法加载.ts文件。 这是我们尝试的代码: https://gist.github.com/nathanhillyer/84e46152d7c4c88183b6

    1. 实施NSURLProtocol以捕获.ts个文件的请求。
    2. AVURLAsset实际上避免被截获。不知何故,网络请求不会被捕获。 (不知道为什么)

4 个答案:

答案 0 :(得分:10)

让我们从真正的好消息开始 - iOS 10及更高版本 - 开箱即用。 不再需要黑客入侵。有关更多详细信息,请参阅以下WWDC16会话,了解HTTP Live Streaming中的新功能: https://developer.apple.com/videos/play/wwdc2016/504/

现在回到当前状态 - iOS 9及更低版本: 使用AVPlayer,没有。但您可以通过本地HTTP服务器缓存HLS段,并使用AVPlayer播放本地流。

AVPlayer和AVAsset在处理HLS播放时不包含必要的信息(例如,它与MP4静态文件的行为不同)。

TL; DR - 您需要使用HTTP请求来获取段并使用本地HTTP服务器为它们提供服务。

一些公司,包括我正在为之工作的公司,正在使用这种策略。

使用连接以您想要的质量下载片段,重建清单并将其全部展平为一个目录和一个质量,然后使用应用程序内的本地http服务器将其提供给AVPlayer(AVPlayer只能播放HLS通过HTTP提供的流 - 而不是来自文件资产的流。)

有一些边缘情况,例如,如果您想在一次运行中播放和下载,正确重建m3u8清单以及使用磁盘读取的不同AVPlayer状态,则进行缓冲。

我从第一手知识中发现了这一点,他们都有这样一个生产5年的系统和App Store中使用相同解决方案的其他视频产品 - 总共服务于许多用户。

这也是我们为Android找到的最佳解决方案。

答案 1 :(得分:2)

实际上,我们可以让AVPlayer从网络播放视频,但是如果你想缓存下载的数据以便在本地播放,那么AVPlayer现在似乎是不可能的。

幸运的是,有一个很棒的API是AVURLAsset中的resourceLoader对象,您可以通过它对AVPlayer提供对远程音频文件的受控访问。这类似于本地HTTP代理,但没有任何麻烦。

您可以在https://gist.github.com/anonymous/83a93746d1ea52e9d23f

上找到更多详情

答案 2 :(得分:0)

关于NSURLProtocol: 据我了解,它会自行提出请求,因此您的自定义标记/字段/标记将被删除。

我已采用其他方式:将段请求重定向到某个自定义网址方案,只需在协议的canInitWithRequest方法中检查方案。

这种方式很好用。 (花了一个星期来计算整个hls处理的东西......)

答案 3 :(得分:0)

从iOS 10开始,您可以使用AVFoundation在用户的设备可以访问快速,可靠的网络时在他们的设备上下载和存储HLS电影,然后在没有网络连接的情况下观看它们。

AVAssetDownloadURLSession

wwdc2016/504/ session谈论Offline HLS。它是关于使用AVAssetDownloadURLSession(它是URLSession的子类,AVAssetDownloadTasks)下载和持久存储资产的,这里用于管理AVAggregateAssetDownloadTask。此会话中提到的API在iOS10之后可用。

AVAggregateAssetDownloadTask

wwdc2017/504 session在iOS11中引入了AVFoundation

一个AVAssetDownloadTask,用于在单个下载任务的保护下为单个AVAsset下载多个AVMediaSelection。

Apple提供了一个示例项目,用于使用Persist播放和AVAggregateAssetDownloadTask HTTP Live Streams。 Demo doc。该演示项目使用AVAssetDownloadStorageManager

AVAssetDownloadStorageManager

/wwdc2017/504还引入了新的API AVAssets,以管理自动清除下载的// Get the singleton let storageManager = AVAssetDownloadStorageManager.shared() // Set the policy let newPolicy = AVMutableAssetDownloadStorageManagementPolicy() newPolicy.expirationDate = myExpiryDate newPolicy.priority = .important storageManager.setStorageManagementPolicy(newPolicy, forURL: myDownloadStorageURL) 的策略。

  • 有效期
  • 优先级(重要,默认)
{{1}}