唱吧 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 給我。