可能是目前最好的 AVPlayer 音视频缓存方案
阿勒,没想到第一篇文章我就标题党了...
不过,我还真没看到目前有哪个公开的实现方案有做的更好的,可能是我孤陋寡闻,如果你知道更好的方案,一定要留言告诉我,鞠躬..
进入正题,这次的主要内容
-
理解 AVAssetResourceLoaderDelegate 的使用
-
缓存下载的实现
-
VIMediaCache 提供了哪些 API
接下来会介绍通过使用 AVAssetResourceLoader,在不改变 AVPlayer API 的情况下,对播放的音视频进行缓存。
前戏
现在市场上各种各样的应用,充满了多媒体信息,而声音和视频又是体积最大的文件,如果直接使用 URL 通过 AVPlayer 播放,系统并不会做缓存处理,等下次再播又要重新下载,对网络状况差的用户来说这就是灾难。若是下载好再播,同样要等待全部下载完成,也是很痛苦。
我们最理想的缓存方案是:边播放,边缓存。
我在早期加入美拍团队的时候,实际上已经有了边下边播的功能,当时选择了使用 HTTPServer,在本地开启一个 http 服务器,把需要缓存的请求地址指向本地服务器,并带上真正的 url 地址。
早期的美拍都是不到 20s 的短视频,后面加长了视频时间,但考虑到用户设备容量问题,我们只对短视频做视频缓存。一直发展到现在,平台上现在大多数的视频都是长视频,真正使用到缓存功能的频率已经很低。那么问题就来了,HTTPServer 不管我们有没有使用缓存功能,都要在应用打开的时候默默开启,这真的是很浪费了。并且我们引入 HTTPServer 库也会增加一些包体积。
理解 AVAssetResourceLoaderDelegate 的使用
那么在一段寻觅之下,发现了最适合做边下边播缓存的工具。AVAssetResourceLoaderDelegate:一个 iOS 6 就被开放出来,专门用来处理 AVAsset 加载的工具。
AVURLAsset *urlAsset = ...
[urlAsset.resourceLoader setDelegate:<AVAssetResourceLoaderDelegate> queue:dispatch_get_main_queue()];
只要找一个对象实现了 AVAssetResourceLoaderDelegate
这个协议的方法,丢给 asset,再把 asset 丢给 AVPlayer,AVPlayer 在执行播放的时候就会去问这个 delegate:喂,你能不能播放这个 url 啊?然后会触发下面这个方法:
- (BOO