淘票票 iOS 客户端:视频本地代理与缓存方案

简介: 提高客户端视频起播速度一直是比较关键的优化点。如何提高起播速度?除了通过优化网络、提高服务器带宽、优化视频文件码率帧率等常规方案外,还可以从哪些方面进行优化呢?一起来看看吧!

作者| 阿里文娱无线开发专家 德夫

一、概述

提高客户端视频起播速度一直是比较关键的优化点。如何提高起播速度?除了通过优化网络、提高服务器带宽、优化视频文件码率帧率等常规方案外,还可以从以下两个方面进一步优化:
1)预加载视频数据。在端侧通过预加载部分视频数据,使播放器在起播时可立即读取本地 视频数据,实现秒开起播;
2)边播放边缓存。通过将正在播放的视频数据缓存在本地,实现当用户再次播放时,可立 即从本地缓存读取视频数据进行播放,无需再次从网络下载,从而提高起播速度。
对于大部分播放器,出于使用方便简单的考虑,都是播放器内部实现视频数据下载和缓存 功能。大部分播放器都没有暴露数据回调接口,使得视频数据业务层不可获得,因此也无法做 这方面的优化。
所以,视频本地代理与缓存方案,关键解决的是:如何将播放器自带的下载逻辑,移交给 业务层,使播放器只负责接收数据、播放和播控。

二、技术方案

1. 早期基于系统播放器 API 的实现方案

使用系统播放器 AVPlayer,其提供了 resourceLoader ,可以实现前面所述的接管视频数据 下载的能力。
resourceLoader 原本用于自定义的资源下载,当AVURLAsset 所对应的资源系统无法处理时,就会调用 resourceLoader 的一系列回调方法,让业务层处理资源的下载。 其中比较关键的回调是:

image.png

其中 AVAssetResourceLoadingRequest 是 AVURLAsset 的一个数据请求,包含了请求相关的 信息,比如数据请求段等。我们要做的就是根据这些请求信息去获得相应的数据,然后把数据 填充给 AVAssetResourceLoadingRequest,完成这个请求。
通过这样的流程,下载数据的逻辑就移交给了业务层,业务层通过自己创建网络请求,下 载获取到的数据除了填充给 AVAssetResourceLoadingRequest 让播放器正常播放,还可以同时写 入本地做视频缓存。当每次收到 AVAssetResourceLoadingRequest 请求时,可以先尝试从本地读 取缓存数据起播视频。

2. 基于视频本地代理的实现方案

上述基于系统播放器 API 的实现方案,依赖于系统播放器提供的接口。而实际业务场景里, 除了使用系统播放器,可能还会使用一些其他的播放器,例如开源的 ijkplayer 等。这些播放器 不一定提供相应的接口供业务层实现缓存视频数据的功能。因此,一个不依赖播放器实现的方 案就显得更加重要。
因此,淘票票客户端决定采用在端上建立一个本地服务器的方式来实现。通过将视频文件 的网络地址,转换为本地地址,再传给播放器。当播放器开始请求数据时,本地服务器即可获 取该请求,从而接管数据下载等逻辑。
原始的播放器流程(如图 1):

image.png

加入本地服务器后的流程(如图 2):

image.png

基于这个思路,我们开发了 AliSmartVideoCache 组件。

3. AliSmartVideoCache 组件

AliSmartVideoCache 是一套包含视频本地服务器代理、缓存和预加载的组件。 其整体架构(如图 3):

image.png

AliSmartVideoCache 对业务方暴露两个组件,预加载组件和本地代理组件。在设备闲置时, 可以通过预加载组件提前下载部分视频数据,支持指定预加载的数据量以及不同网络环境下预 加载的策略。视频以队列形式预加载。
本地代理组件负责转换视频地址,判断视频资源格式,不同视频格式的本地代理策略以及 本地服务器的维护等。

4. 视频文件缓存

视频的文件缓存部分稍复杂,原因是视频文件缓存数据经常是不连续的。一般情况下,如 果用户从头开始播放视频,那么视频文件理论上是从头开始下载,数据连续。但当用户在播放 过程中,拖动进度条到任意位置时,缓存就会出现下载的数据不连续的情况。
为了最大化缓存所下载的数据,我们开发了基于单个文件的视频缓存组件。其通过在文件 头部维护一个映射表(见图 4),将数据在原始文件的偏移量与本地缓存文件的偏移量建立映射 关系,从而实现不连续的视频数据在缓存文件中的连续缓存(类似 Sparse File)。

image.png

5. 整体流程

image.png

当本地代理收到视频下载请求后,会先通过业务方指定的规则,从 url 规则来判断视频的 格式类型。如果是 HLS 视频,就会走解析 playlist 文件,替换分片地址的流程;如果是其他视 频格式,则先查找本地缓存数据,将已有缓存数据直接返回,缺失的部分发起网络请求。从网 络获得的数据,在返还给播放器的同时,根据本地策略决定是否写入本地缓存。

三、总结

以上提到的技术,针对一些小细节和特殊情况的处理还是要额外留心的。 比如按照前面的设想,缓存视频开头部分的数据有助于提高视频起播速度,但有些视频的moov 段是置后的,也就是说播放器要起播,必须直接跳到文件尾去下载部分数据,解析 moov 元数据。如此一来,缓存开头部分数据所带来的起播速度提升就会打折扣。因此,在处理淘票票的实际业务场景时,协调服务端做了二次转码来保证移动 moov 段到文件头部。
另外前面也提到了因为用户拖拽而导致的下载策略变化,还需要考虑一种情况,就是服务 端不支持 206 partial content。在这种情况下,客户端不能通过 Content-Range 去指定所需要的 数据位置,请求的数据永远是从文件起始位置开始的,下载策略就需要针对这种情况做特殊处理。
还有比如网络请求失败、重试、数据错误的异常情况,设备磁盘空间不够导致缓存类新建 或扩展文件失败的处理等等,都需要小心处理。
在使用这套视频播放器本地代理组件并配合业务层预加载逻辑后,系统播放器和第三方播 放器的视频秒播率和有效 vv 率都得到了显著的提高,其中秒播率更是达到 95% 以上,效果还是很不错的。

相关文章
|
4天前
|
存储 数据建模 数据库
IOS开发数据存储:什么是 UserDefaults?有哪些替代方案?
IOS开发数据存储:什么是 UserDefaults?有哪些替代方案?
47 0
|
6月前
|
移动开发 安全 数据安全/隐私保护
ios安全加固 ios 加固方案
4.1字符串加密字符串会暴露APP的很多关键信息,攻击者可以根据界面显示的字符串,快速找到相关逻辑的处理函数,从而进行分析破解。加密字符串可以增加攻击者阅读代码的难度以及根据字符串静态搜索的难度。
|
6月前
|
Linux Android开发 iOS开发
基于.Net开发的ChatGPT客户端,兼容Windows、IOS、安卓、MacOS、Linux
基于.Net开发的ChatGPT客户端,兼容Windows、IOS、安卓、MacOS、Linux
93 0
|
4天前
|
移动开发 安全 数据安全/隐私保护
ios安全加固 ios 加固方案
ios安全加固 ios 加固方案
33 1
ios安全加固 ios 加固方案
|
4天前
|
安全 数据安全/隐私保护 虚拟化
iOS应用加固方案解析:ipa加固安全技术全面评测
iOS应用加固方案解析:ipa加固安全技术全面评测
49 3
|
4天前
|
移动开发 前端开发 数据安全/隐私保护
【教程】Ipa Guard为iOS应用提供免费加密混淆方案
【教程】Ipa Guard为iOS应用提供免费加密混淆方案
30 0
|
4天前
|
安全 数据安全/隐私保护 虚拟化
iOS应用加固方案解析:ipa加固安全技术全面评测
iOS应用加固方案解析:ipa加固安全技术全面评测
86 0
|
4天前
|
移动开发 安全 数据安全/隐私保护
ios安全加固 ios 加固方案
ios安全加固 ios 加固方案
46 0
|
4天前
|
移动开发 安全 数据安全/隐私保护
【教程】Ipa Guard为iOS应用提供免费加密混淆方案
概述:使用ios加固工具对ios代码保护,保护ios项目中的核心代码,
|
7月前
|
缓存 API Nacos
在MSE微服务引擎中为Nacos客户端启用本地缓存
在MSE微服务引擎中为Nacos客户端启用本地缓存
79 1