ShortMediaCache视频缓存逻辑分析

一套基于AVPLayer短视频播放缓存库ShortMediaCache GitHub地址

主要特点:

  • 1.为短视频量身设计,接入方便,不侵占业务
  • 2.边播变缓存,缓存后直接播放
  • 3.预加载功能,秒播下一条短视频
  • 4.自动缓存管理

业务背景

公司电商APP接入短视频模块也有半年多的时间了,之间一直在忙着完善业务功能,现在是时候沉淀下来总结这一路来的收获。

视频播放对于ios开发来说其实并不是一个难事儿,简单几行代码就能实现,确实,最初的短视频播放也是基于此,给定视频url直接丢给系统播放器(AVPlayer)就可以播放了。但是随着短视频业务发力,短视频模块在APP业务中承担了更多更重要的角色,如何提升短视频的播放速度变得尤为重要,随之便提出了短视频边播变缓存,短视频预加载相关功能要求。

业务分析,公司APP主业务是电商,短视频作为为电商引流业务,提高APP活跃度的业务模块,同时在APP其他业务功能中也存在视频播放,例如商品详情页面商品介绍,基于此设计之初并不打算将所有的播放业务耦合在一起,因为短视频的播放概率远远大于其他长视频,依次业务需求大致分为2类逻辑,短视频和在线播放,对于短视频统一按照短视频播放模块来执行边播变缓存,而其他的相对比较长一些的视频则直接在线播放也不缓存,此处也不做过多介绍。

边播边缓存的实现

短视频播放特点:
1、全屏播放
2、快速播放,争取每个短视频都能秒播
3、内容高度浓缩,无需进度条与拖拽进度
4、精彩的短视频可能会被重复观看几次
5、其他(声音控制、流量)

基于以上特点,可以大致将短视频播放划分为2个层级,第1层为播放器层,第2层为缓存层,播放器层是基于缓存层的,主要负责播放过程控制和UI展现,比如暂停,继续,声音控制,暂停播放显示控制以及其他的UI;播放器层对于每个APP可能会有不同的业务需求,实现的功能也大不相同,故将缓冲层与播放器层剥离,而缓存层则主要负责短视频内容的下载,预加载,缓存管理,这也是ShortMediaCache的主要功能。

如何从缓存播放

ShortMediaCache缓存播放逻辑大致的实现结构如下图:

3629414030-5b88f46e033f7_articlex.png

对于AVPlayer连接播放器层与缓存层的数据交互是通过自定义实现AVAssetResourceLoaderDelegate协议实现的,在播放器加载的过程中,播放器会通过AVPlayerItem向AVURLAsset的resourceLoader获取需要加载数据信息,比如加载的数据偏移,大小等,最终这些数据请求(AVAssetResourceLoadingRequest)会到达其代理(AVAssetResourceLoaderDelegate)对象,代理对象根据请求数据的位置和大小,去读取相关文件缓存数据,然后回填给请求,以此来响应播放器的数据缓冲请求,与此同时缓存层通过网络请求将下载下来的数据写入文件保存。

对于AVAssetResourceLoaderDelegate协议主要需要实现以下方法:

- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoadershouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest;

播放器的数据加载请求会放到loadingRequest里面,通过其dataRequest对象的requestedOffset和requestedLength可以知道本次数据请求的区块,从缓存文件中按需读取数据填充后执行finishLoading方法即可完成本次数据请求

- (void)resourceLoader:(AVAssetResourceLoader *)resourceLoader didCancelLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest;

请求取消回调

下载

对于下载应该放到子线程中去通过NSURLSession来实现,因为视频文件可能之前已经缓存了部分,需要从已缓存的位置大小处继续下载缓存,在每次开启下载前需要去读取已缓存文件的大小,并设置请求头部字段Range便可从此处继续下载后面未下载的部分。

NSString *range = [NSString stringWithFormat:@"bytes=%ld-", (long)cachedSize];
[downloadRequest setValue:range forHTTPHeaderField:@"Range"];

由于针对短视频的播放不存在进度拖拽或seek功能,所以每次下载到的数据可以直接通过缓存管理的相关方法直接append到缓存文件末尾。
因为短视频的播放首要任务就是保证当前单个视频的流畅播放,所以在理论上只会存在一个下载任务来独享所有的下载带宽,当在空闲状态的情况下才适合去做其他的短视频资源的预加载。

缓存管理

缓存主要创建了三个目录管理,分别为temp、media和trash目录,缓存分为临时缓存和最终缓存,当短视频资源未下载完时是放在一个目录下的(temp目录)、而当视频资源缓存完时移动到另外一个目录(media),这样分别存放便能方便读取和管理两种状态的缓存,所有需要删除的缓存文件都是先移入trash目录,随后再删除以此来保证较高的删除效率。所有文件命名使用的是视频资源的url md5值保证唯一性。

缓存应该具有自动管理功能,以防止其无限膨胀,默认配置下ShortMediaCache允许临时缓存最多保存1天,最大100Mb,而最终缓存则允许最多保存2天最大200Mb,如果业务需要可以自定义ShortMediaCacheConfig配置实现。

预加载

要实现下一个视频或者几个视频能快速的播放起来,预加载的下载任务应该和正常的边下边播任务区分开,因为首先应该保证正在播放的短视频能顺畅的播放,所以边下边播任务优先级应该高于预加载任务,在没有边下边播任务时才能执行预加载任务,并且当有新的边下边播任务时应当停止当前的预加载任务,首要执行边下边播任务。

ShortMediaCache提供了预加载功能实现,通过调用ShortMediaManager以下方法:

- (void)resetPreloadingWithMediaUrls:(NSArray<NSURL *> *)mediaUrls;

使用者可以多次调用此方法,来不断更新需要预加载的资源队列

ShortMediaCache使用方式

下载源码文件,将ShortMediaCache文件夹引入工程, 通过ShortMediaResourceLoader来创建AVPlayer需要播放视频的AVPlayerItem即可

#import "ShortMediaResourceLoader.h"
ShortMediaResourceLoader _resourceLoader = [ShortMediaResourceLoader new];
AVPlayerItem _playerItem = [_resourceLoader playItemWithUrl:videoUrl]; 
AVPlayer _player = [AVPlayer playerWithPlayerItem:_playerItem];

正常情况下应该持有_resourceLoader对象

预加载视频

[[ShortMediaManager shareManager] resetPreloadingWithMediaUrls:preloadUrls];

preloadUrls存放需要预加载的视频url

持续更新

ShortMediaCache大致类调用逻辑图如下:

3647638192-5b890535995e2_articlex.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345