淘票票 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% 以上,效果还是很不错的。

相关文章
|
14天前
|
缓存 NoSQL Java
SpringBoot实现缓存预热的几种常用方案
SpringBoot实现缓存预热的几种常用方案
|
5月前
|
缓存 NoSQL Java
聊聊分布式应用中的缓存方案(一)
聊聊分布式应用中的缓存方案(一)
40 0
|
17天前
|
存储 缓存 安全
基于iOS平台的高效图片缓存策略实现
【4月更文挑战第22天】 在移动应用开发中,图片资源的加载与缓存是影响用户体验的重要因素之一。尤其对于iOS平台,由于设备存储空间的限制以及用户对流畅性的高要求,设计一种合理的图片缓存策略显得尤为关键。本文将探讨在iOS环境下,如何通过使用先进的图片缓存技术,包括内存缓存、磁盘缓存以及网络请求的优化,来提高应用的性能和响应速度。我们将重点分析多级缓存机制的设计与实现,并对可能出现的问题及其解决方案进行讨论。
|
17天前
|
存储 缓存 算法
实现iOS平台的高效图片缓存策略
【4月更文挑战第22天】在移动应用开发中,图片资源的处理是影响用户体验的重要因素之一。特别是对于图像资源密集型的iOS应用,如何有效地缓存图片以减少内存占用和提升加载速度,是开发者们面临的关键挑战。本文将探讨一种针对iOS平台的图片缓存策略,该策略通过结合内存缓存与磁盘缓存的机制,并采用先进的图片解码和异步加载技术,旨在实现快速加载的同时,保持应用的内存效率。
|
1月前
|
存储 缓存 iOS开发
基于iOS的高效图片缓存策略实现
【4月更文挑战第9天】在移动应用开发中,图片资源的加载与缓存是影响用户体验的重要因素之一。特别是对于iOS平台,合理设计图片缓存策略不仅能够提升用户浏览图片时的流畅度,还能有效降低应用程序的内存压力。本文将介绍一种针对iOS环境优化的图片缓存技术,该技术通过多级缓存机制和内存管理策略,实现了图片快速加载与低内存消耗的目标。我们将从系统架构、关键技术细节以及性能评估等方面展开讨论,为开发者提供一套实用的图片缓存解决方案。
20 0
|
1月前
|
存储 缓存 iOS开发
实现iOS平台的高效图片缓存策略
【4月更文挑战第4天】在移动应用开发中,图片资源的加载与缓存是影响用户体验的关键因素之一。尤其对于iOS平台,由于设备存储和内存资源的限制,设计一个高效的图片缓存机制尤为重要。本文将深入探讨在iOS环境下,如何通过技术手段实现图片的高效加载与缓存,包括内存缓存、磁盘缓存以及网络层面的优化,旨在为用户提供流畅且稳定的图片浏览体验。
|
2月前
|
存储 缓存 监控
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(数据更新场景策略和方案分析)
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(数据更新场景策略和方案分析)
14 0
|
2月前
|
缓存 NoSQL 前端开发
【Redis技术专区】「实战案例」谈谈使用Redis缓存时高效的批量删除的几种方案
【Redis技术专区】「实战案例」谈谈使用Redis缓存时高效的批量删除的几种方案
45 0
|
4月前
|
缓存 NoSQL 关系型数据库
Mysql的缓存方案
Mysql的缓存方案
50 0
|
5月前
|
缓存 Java 数据库连接
干翻Mybatis源码系列之第八篇:Mybatis提供的缓存方案细节注意
干翻Mybatis源码系列之第八篇:Mybatis提供的缓存方案细节注意