拒绝卡顿,揭秘盒马鲜生 APP Android 短视频秒播优化方案

盒马最初为了保证进入画面时不是空白页面而增加了封面图显示,在播放时隐藏 。从体感指标可以看出,即便是优化前,体感播放时间很短,只有 200ms 左右(不包含滑动过程) 。由于滑动过程中,到视频正式播放有约 600ms 左右时间显示封面,随后又迅速显示播放画面,此时用户仍有强烈的屏幕闪烁和顿挫感,体验极差 。
解决思路:在滑动过程中就显示视频首帧画面,不再显示封面 , 则播放时不再产生顿挫感 。这里的优化需要结合出流慢问题一起优化 。
◆出流速度慢(播放体感慢)
服务端:服务端造成的出流速度慢,一般是文件大,网络链路差造成 。可用 H.265 和 CDN 加速优化
客户端:客户端播放需要经历下载->加载+解码->渲染三个步骤,并且三个步骤为线性执行 。所以在窗口播放画面前必然需要经过 1s 左右的准备工作 。这里可以考虑提前执行下载->加载+解码 。
优化方案选型
在优化前期,我们考虑了三种优化方案 。
方案一:双播放器+预下载
优点:占内存?。?思路简单 。
缺点:优化力度有限 , 无法同时兼顾上滑和下滑 。
方案二:自定义三播放器管理+预下载
优点:同时兼顾上下翻页,体验接近抖音 。
缺点:播放器管理与回收实现复杂,容易错乱;占用内存高 。
方案三:三播放器(基于的缓存机制实现)+预下载
【拒绝卡顿,揭秘盒马鲜生 APP Android 短视频秒播优化方案】优点:同时兼顾上下翻页 , 体验接近抖音,缓存机制由托管 。
缺点:占用内存高,频繁创建和销毁播放器 。
最终因为性价比因素,选择了第三个方案 。

拒绝卡顿,揭秘盒马鲜生 APP Android 短视频秒播优化方案

文章插图
方案三原理:翻页前
方案三原理:翻页后
具体优化方案
多播放器改造
为了解决体感上的顿挫和出流慢的问题,采用多播放器结合方案进行改造,步骤如下:
1. 设置缓存数量:利用特性,配置 ,确保内存中存在 3 个 (缓存的 1 个  , 预创建 1 个 , 当前 ) 。
mRecyclerView.setItemViewCacheSize(1); // 设置缓存数量
2.重写的 ,用于创建播放器,并预加载解码视频内容,播放器控制解析到首帧时暂停 。此时尚未回调,画面未渲染至屏幕 。
3. 监听控制即将移除屏幕的播放器暂停,并 (0),方便滑回屏幕时立即播放 。
4. 监听控制即将进入屏幕的播放器开始播放 。
注意:由于在期间已解码完成,这里只需要进入屏幕 1px,就会立即触发的绘制(只会执行一次),即进入窗口的内容会显示视频的首帧画面 。
5. 重写的 , 由于当前即将移出屏幕,移出方向上屏幕外的将被回收 。此时回收并销毁播放器 。
多播放器+ 原理图
三播放器让沉浸式短视频的体验大幅提高,主要解决了以下问题:
预下载优化
拒绝卡顿,揭秘盒马鲜生 APP Android 短视频秒播优化方案

文章插图
前面讲到了多播放器实现翻页秒播能力 , 在体验上有了非常大的改善 , 但由于预创建的播放器在加载时,同时需要下载视频文件,导致这里的下一个播放器准备好视频的时间会增加到 1s 左右 。如果用户在播放器加载解码完成前滑至该视频 , 则会出现明显的黑屏,带来非常差的体验 。
由于预加载的时间过长 , 且无法预知用户是否会快速滑动 。这里需要提前进行下载和快速滑动检测 。
关于预下载,我们首先要知道播放器内部播放过程 。这里的本地代理是视频缓存机制实现的,具体参照下一章节 。
播放器内部流程
◆预下载策略
这里,我们为了节约请求网络数据的过程,在播放之前提前下载视频的首帧片段,采用如下策略:
◆快滑定义
当用户快速翻页时( 调用之前又滑了一下),不会触发 ,  会触发多次 。在中判断与的差值如果> 1 则表示用户至少快速翻页 1 次,此时定义为快滑状态,应当停止预下载和播放器预加载 。
当回调时,说明用户没有继续翻页,此时取消快滑状态 。开始执行预下载和恢复播放器预加载 。
预下载流程图
缓存优化
目前盒马使用的播放器为淘宝内部播放器 。播放器本身不存在文件缓存和预下载功能 。在播放器重新创建后 , 即便是同一个视频也不会有文件缓存,需要重新下载 。这里引入一个开源缓存框架“com.:” 。
◆方案原理
播放器播放的地址代理给本地的缓存服务,缓存服务负责转发数据流的同时进行文件保存如:
视频地址为:****.mp4 。
本地代理地址为::8888 (假设端口号分配为 8888) 。
代理后的地址为:本地代理地址 +视频地址(URL编码) 。