唱吧 iOS 团队为了解决音视频在线播放的缓存问题,开发了 KTVHTTPCache 这个框架。设计之初是为了解决音视频在线播放的缓存问题,但其本质是对 HTTP 请求进行缓存,对传输内容并无限制,所以应用场景不限于音视频在线播放,也能够用于文件下载、图片加载、普通网络请求等场景。前端
对于有重度音视频在线播放需求的应用,缓存无疑是必不可少的功能。目前经常使用的方案有 Local HTTP Server 和 AVAssetResourceLoader 两种。两者实现及原理虽有不一样,但本质都是要 Hook 到播放器资源加载的请求,从而接管资源加载逻辑。根据缓存状态,自行决定是否须要经过网络加载资源。从应用场景的角度看,两者有一个比较大的差别是前者能够搭配任意前端播放器,然后者只能配合 AVPlayer 使用。git
我的认为,因为 AVAssetResourceLoader 是黑盒且会干预 AVPlayer 自己的播放逻辑,致使坑多且难排查。而且不一样的版本之间会有行为差别(例如近期发如今最新的 iOS 11 系统中,本来工做正常的代码,由于一个细小的行为变化,引起了一个 Bug),去适配它的逻辑会有不小的工做量。相反 Local HTTP Server 是彻底 Open Source,咱们可以全面接管资源加载逻辑,能够尽量的规避缓存策略的引入带来的风险。github
KTVHTTPCache 由 HTTP Server 和 Data Storage 两大模块组成。前者负责与 Client 交互,后者负责资源加载及缓存处理。为方便拓展,Data Storage 为独立模块,也可直接与 Client 交互(例如可与 AVAssetResourceLoader 配合使用)。缓存
以网络使用最小化为原则,设计了分片加载数据的功能。有 Network Source 和 File Source 两种用于加载数据的 Source,分别用于下载网络数据和读取本地数据。经过分析 Data Request 的 Range 和本地缓存状态来对应建立。安全
例如一次请求的 Range 为 0-999,本地缓存中已有 200-499 和 700-799 两段数据。那么会对应生成 5 个 Source,分别是:bash
它们由 Data Sourcer 进行管理,对外仅暴露一个 Read Data 的接口,根据当前的 Read Offset 自行选择向外界提供数据的 Source。网络
// 使用简单,基本能够忽略集成成本
// 启动(全局启动一次便可)
NSError * error;
[KTVHTTPCache proxyStart:&error];
// 使用
NSString * URLString = [KTVHTTPCache proxyURLStringWithOriginalURLString:@"原始 URL"];
AVPlayer * player = [AVPlayer playerWithURL:[NSURL URLWithString:URLString]];复制代码
在音视频缓存上,咱们一共采用过以下 4 个方案:并发
AVPlayer 在播放时会优先根据 Response Header 中的 Content-Type 判断当前资源是否能够播放。当 Content-Type 没法给出有效信息时再去判断 URL 中的 Path Extension。app
对应关系以下:框架
URL | Content-Type | 是否可播 |
---|---|---|
changba.com/video.mp4 | video/mp4 | YES |
changba.com/video.mp4 | application/octet-stream | YES |
changba.com/video | video/mp4 | YES |
changba.com/video | application/octet-stream | NO |
所以要想让 AVPlayer 正常播放,Content-Type 和 Path Extension 中至少能提供一个有效信息,不然将直接报 Error。
在本地 Server 中有一个 Socket 用于接收 AVPlayer 发出的请求。若是在 AVPlayer 为非播放状态时锁屏,一段时间后再唤起 App,FD 虽然还在,但 Listen 的端口会被回收,致使 FD 接收不到事件,AVPlayer 发出的请求也就没法被本地 Server 接收到。咱们的解决办法是在作 URL 映射时 Ping 一下本地 Server,若是 Ping 不通,会重启本地 Server。
项目已经开源,GitHub 地址: github.com/ChangbaDevs…
对重度影音类应用而言,音视频缓存属于比较重要的一环,对稳定性也有比较高的要求,咱们在这上走过一些弯路、踩过一些坑。但愿 KTVHTTPCache 的开源能给你们带来一些帮助。也很是欢迎你们在项目中使用,若是遇到问题能够在 GitHub 提 Issue 给我。