美文网首页
基于KTVHTTPCache实现的视频缓存和预加载

基于KTVHTTPCache实现的视频缓存和预加载

作者: sun_glory | 来源:发表于2020-04-28 21:23 被阅读0次
    前言

    KTVHTTPCache是唱吧开源的一套音视频缓存框架。因目前所做的项目有视频播放的需求,因此在某个版本的迭代中,接入了KTVHTTPCache,体验不错。
    对于视频播放缓存的方案,常用的有Local HTTP ServerAVAssetResourceLoader 两种。本质上都是截获请求加载的url,再加入具体的视频缓存逻辑。有一个区别点在于AVAssetResourceLoader只能配合AVPlayer 使用。

    KTVHTTPCache的结构设计

    KTVHTTPCacheHTTP ServerData Storage两大模块组成。前者负责与Client 交互,后者负责资源加载及缓存处理。


    HTTP ServerData StorageKTVHTTPCache 两大重要组成部分, HTTP Server 主要负责与用户交互,也就是最顶层,最直接与用户交互(比如下载数据),而 Data Storage 则在后面为 HTTP Server 提供数据,数据主要从 DataSourcer 中获取,如果本地有数据,它会从 KTVHCDataFileSource 中获取,反之会从 KTVHCDataNetworkSource中读取数据,这里会走下载逻辑(KTVHCDownload)

    工作流程如下
    1.Client发出的请求被 HTTP Srever 接收到,HTTP Server 通过分析 HTTP Request 创建用于访问 Data StorageData Request 对象。
    2.HTTP Server 使用 Data Request 创建 Data Reader,并以此作为从Data Storage 获取数据的通道。
    3.Data Reader 分析 Data Request 中的 Range 创建对应的网络数据源 Data Network Source 和文件数据源 Data File Source,并通过 Data Sourcer 进行管理。
    4.Data Sourcer开始加载数据。
    5.Data ReaderData Sourcer 读取数据并通过 HTTP Server 回传给 Client

    HttpServer

    这层设计比较简单,主要是用了 CocoaHTTPServer 来作为本地的 HttpServerHttpServer 说白了就是一个手机端的服务器,用来与用户(作者说的 client)交互,用户提出数据加载需求后,它会从不同的地方来获取数据源,如果本地没有会从网络中下载数据。它主要的作用是 hook 播放器的网络请求,进行数据的加载。它主要的类如图:

    • KTVHCHTTPServer:是一个单例,用来管理 HttpServer 服务,负责开启或关闭服务;
    • KTVHCHTTPConnection:它继承于 HTTPConnection,表示一个连接,它主要为 HttpServer 提供 Response。
    • KTVHCHTTPRequest:一个请求,也就是一个数据模型;
    • KTVHCHTTPResponse:一个 Response;
    • KTVHCHTTPResponsePing:主要用来 ping 时的 Response;
    • KTVHCHTTPURL:主要用来处理 URL,比如把原 Url 生成 proxy url;
    DataStroage

    主要用来缓存数据,加载数据,也就是提供数据给 HttpServer。上面代码中关键的一句代码 [KTVHCHTTPResponse responseWithConnection:self dataRequest:dataRequest],它会在这个方法的内部使用KTVHCDataStorage 生成一个 KTVHCDataReader,负责读取数据。生成 KTVHCDataReader 后通过 [self.reader prepare] 来准备数据源 KTVHCDataSourcer,这里主要有两个数据源,KTVHCDataFileSourceKTVHCDataNetworkSource,它实现了协议 KTVHCDataSourceProtocolKTVHCDataNetworkSource 会通过 KTVHCDownload 下载数据。

    • KTVHCDataStorage: 是一个单例,它负责管理整个缓存,比如读取、保存和合并缓存;
    • KTVHCDataReader:主要用来读取数据;
    • KTVHCDataRequest:用来请求数据,表示一个请求;
    • KTVHCDataResponse:一个数据响应;
    • KTVHCDataReader:读取数据;
    • KTVHCDataCacheItem:缓存数据模型,表一个缓存项;
    • KTVHCDataCacheItemZone:缓存区,一个缓存项中会有多个缓存区,比如0-99,100-299 等;
    • KTVHCDataSourcer:数据源中心,负责处理不同数据源,它包含有一个数据队列 KTVHCDataSourceQueue
    • KTVHCDataSourceQueue:数据队列;
    • KTVHCDataSourceProtocol:一个协议,作为数据源时需要实现这个协议;
    • KTVHCDataFileSource:本地数据源,实现了 KTVHCDataSourceProtocol 协议;
    • KTVHCDataNetworkSource:网络数据源,实现了KTVHCDataSourceProtocol 协议;
    • KTVHCDataUnit:数据单元,相当于一个缓存目录,比如一个视频的缓存;
    • KTVHCDataUnitItem:数据单元项,缓存目录下不同片段的缓存;
    • KTVHCDataUnitPool:数据单元池,它是一个单例,含有一个 KTVHCDataUnitQueue
    • KTVHCDataUnitQueue:数据单元队列,保存了多个 KTVHCDataUnit,它会以 archive 的方式缓存到本地;
    接入缓存
    - (void)initCache {
        NSError *error = nil;
        [KTVHTTPCache proxyStart:&error];
        if (error) {
            NSLog(@"Proxy Start Failure, %@", error);
        }
        // 设置缓存最大容量
        long long maxLength = 300 * 1024 * 1024;
        [KTVHTTPCache cacheSetMaxCacheLength:maxLength];
    }
    
    - (void)useCacheUrl {
    NSString *proxyURLString = [KTVHTTPCache proxyURLStringWithOriginalURLString:URLString];
    [AVPlayer playerWithURL:[NSURL URLWithString: proxyURLString]];
    

    KTVHTTPCache的接入特别简单,几乎零成本,可以配置最大缓存容量。需要注意的是,播放使用的url是从KTVHTTPCache取出来的url

    实现预加载

    当播放视屏列表时,最好在播放当前视频时,能够预加载下几个即将要播放的视频。
    可以使用NSOperationQueue操作队列在实现在后台提前预加载待播放的视频。在当前视频的链接配置完毕时,可以根据业务实际需要,将下一个或下几个视频url用NSOperation加到NSOperationQueue中,在后台进行预加载,这样当用户滑动视频,下一个视频就已经是提前预加载好的了。当然,这里只是简单提供思路,项目中使用NSOperationQueue也是很方便就能实现的,可以控制最大并发数量,是预加载当前index前面的视频还是后面的视频,弱网是否执行预加载,具体的预加载逻辑还是要结合业务来操作。

    读懂「 唱吧KTVHTTPCache 」设计思想

    唱吧 iOS 音视频缓存处理框架

    相关文章

      网友评论

          本文标题:基于KTVHTTPCache实现的视频缓存和预加载

          本文链接:https://www.haomeiwen.com/subject/gxzbwhtx.html