当前位置:   article > 正文

ExoPlayer播放器分析及优化

exoplayer

坚持问题导向,因此本文以视频翻页播放功能为问题场景(类似抖音),介绍exoplayer播放器使用及优化。
包含以下几部分:

  1. 播放器基础介绍
  2. exoplayer架构介绍,包括: 视频本地缓存、 视频数据加载
  3. 视频翻页如何实现零延迟启播
  4. 如何优化流量使用
  5. 如何优化内存占用
  6. 其他问题及优化项

一. 播放器基础介绍

播放器基础流程

二. exoplayer架构介绍

架构
LoadControl: 控制视频加载(内存)
Cache: 视频缓存(本地文件)
Extractor: 解包,提取音视频数据

1. 视频本地缓存功能

因视频文件通常比较大,如何使用有限的本地存储空间缓存视频数据;
exoplayer缓存设计方案 - 分段写入

  1. 从网络加载视频数据时,分片写入缓存文件,默认大小为5M (CacheDataSink#DEFAULT_FRAGMENT_SIZE)
  2. 缓存文件记录视频信息: 视频id, 视频流地址,时间戳
  3. 根据视频地址可查询对应视频所有缓存片段
  4. 使用lru策略管理缓存空间

优点:

  1. 使用有限空间即可缓存最近播放视频数据
  2. 解决播放过程遇到进度拖动导致缓存碎片问题
  3. 支持预加载

预加载播放

2. 视频数据加载功能

缓存使用:
加载视频数据时,网络请求跳过所有缓存片段,减少流量消耗
视频加载-缓存

按需加载,可设置最大缓冲时间或大小
指定时间:DefaultLoadControl#DEFAULT_MAX_BUFFER_MS
指定大小:DefaultLoadControl#DEFAULT_VIDEO_BUFFER_SIZE(有几个类型,分别指定最大值)
优点:

  1. 控制内存占用
  2. 减少流量消耗:如果用户没看完就划走,但却加载整个视频的数据,造成带宽浪费。
    按需加载

三. 视频翻页如何实现零延迟启播

实现零延迟启播,就要求视频一定在触发播放前就完成首帧解码工作。因此优化解码不是主要突破点(因为优化不了多少),关键是要打提前量。
因此主要有以下几点:

  1. 预加载:提前缓存视频部分数据到本地
  2. 提前播放:视频切换预判并提前播放

播放优化

四. 如何优化流量使用

  1. 视频预加载头部数据时,结合视频码率计算需要预加载的数据大小, 尽量减少预加载数据量;
  2. 高端机型可使用h265;
  3. 播放视频过程中,设置最大缓冲时长,避免用户未看完而加载整个视频造成浪费;参考上边:视频数据加载功能

五. 如何优化内存占用

  1. 播放器实例复用,不要创建太多实例
  2. 设置最大缓冲时长,exoplayer默认好像60s;如果设置了循环播放,即使视频数据只有15s, 内存中也是加载60s数据的。(解决: MediaPeriodQueue#MAXIMUM_BUFFER_AHEAD_PERIODS 修改为2,最多只填充2个视频数据)

六. 其他问题及优化项

  1. 首帧对齐:使用首帧作为封面,视频启播成功后,隐藏封面。 如果没对齐,启播时画面肯定会抖动。
  2. 如何判断启播成功,并隐藏封面:VideoListener#onPlayerStateChanged STATE_READY和VideoListener#onRenderedFirstFrame都完成回调时,才可认为启播成功,此时隐藏封面,两者缺一不可。 如果满足STATE_READY但onRenderedFirstFrame未完成,此时隐藏封面,视频画面是黑色的。
  3. SimpleExoPlayer大部分接口都比较耗时,如果主线程调用,界面会比较卡顿。因此播放器接口调用需要放在子线程。
  4. SimpleExoPlayer不是线程安全的(所有调用保证在同一子线程,不然会有crash),同时播放器回调接口必须与调用接口一致; 参考SimpleExoPlayer构造函数中looper参数的代码注释。
  5. 播放器识别视频格式使用头部数据探测的方式,比较耗时。因小视频格式固定,所以修改探测顺序,提升速度。(解决:DefaultExtractorsFactory#createExtractors, 把使用的格式放在第一位)
本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号