视频在滑动列表中的异步缓存和播放
来源:互联网 发布:retas for mac 下载 编辑:程序博客网 时间:2024/06/07 12:51
原文 blog.waynell.com
在 ListView 或者 RecyclerView 列表中播放视频
最近在Github上看到VideoPlayerManager这么一个项目,目的在是ListView和RecyclerView中播放小视频,模仿了Instagram中滑动到可见视频项时开始播放该视频,滑动至不可见时停止视频播放的功能
但是该项目存在几个问题:
快速上下滑动列表后,无法再播放视频,有时还会直接Crash
不支持网络视频的异步缓存
故在该项目的基础上进行了优化,并且支持网络视频的异步缓存
网络视频的异步缓存
视频的缓存其实跟图片缓存大致是一样的,现在图片缓存框架很多,但是根本原理都是网络下载+内存缓存+本地缓存这三大块组成。而视频的缓存只需要跳过内存缓存就可以了,当发视频文件未下载时就去下载并本地缓存,下次就直接从本地缓存读取视频文件信息,所以基于图片缓存框架不难实现视频文件的缓存功能。
这里我采用了Glide来实现视频缓存,Glide不仅支持图片缓存还支持对普通文件缓存,所以使用Glide可以很简单的就能实现视频文件的缓存
基于TextureView的视频播放控件
Android原生提供了一个视频播放控件 - VideoView,但VideoView是基于SurfaceView实现的,SurfaceView会单独一个窗口用来绘制,它不在View hierachy中,显示也不受View的属性控制,不能进行平移,缩放等变换,也难以放在ListView或者ScrollView中,一些View中的特性也无法使用。
为了弥补SurfaceView的不足,Android在4.0中加入了TextureView,它并没有创建一个单独的窗口用来绘制,这使得它可以像一般的View一样执行一些变换操作,设置透明度等,也很方便的放在其它ViewGroup中
所以要在ListView或者RecyclerView中播放视频,我们就需要实现基于TextureView的VideoView,实现代码参考ViewVideo就可以了
视频在滑动列表中的自动播放和停止
要实现视频的自动播放和停止,我们需要计算每个item中列表中的可见比。比如当某item可见比大于70%时,则该item视为可见的,激活视频播放。反之视为不可见,停止视频播放
这里简单说下实现原理,主要分为下面三步
在列表滑动时,判断滑动方向
根据滑动方向判断相邻的item是否视为可见,比如在下滑列表时,当前可见item的可见比在逐渐减小,而下一项的可见比在逐渐加大,当前item可见比低于70%时停止播放,下一项可见比大于70%时就开始播放
在快速滑动列表时,不检测item的变化(避免卡顿);在滑动停止时,查找当前可见item中可见比最大的item,如果该item和之前可见的item不一样时,则激活该item
列表中视频播放的性能问题
视频的播放主要使用了MediaPlayer,MediaPlayer的状态图如下所示:
state diagram
state diagram
从图中可以看出,视频在开始播放前需要首先通过setDataSource()进行初始化,然后通过prepare()或者prepareAsync()进行播放前准备工作,最后准备完成后通过start()操作才开始播放视频
其中prepare()操作是相当耗时的,这一步操作绝不应该在UI线程中调用,而prepareAsync()则是使用异步的方式调用,所以在list列表中播放视频应该使用prepareAsync()来准备视频
光靠prepareAsync()这一步,可不足以保证list滑动时每帧耗时不超过16ms,像setDataSource(),reset(),release()这些操作都是比较耗时的,虽然达不到引起ANR的程度,但是对于list滑动的流畅性却影响很大
解决方案
这里我采用了将MediaPlayer的全部操作都放在一个单独的线程中去处理,事件回调则通过ui Handler post回ui线程,这样就可以保证list滑动的流畅性
效果预览
代码具体的使用和详细实现方法都已放到Github上
项目地址:https://github.com/waynell/VideoListPlayer
- 视频在滑动列表中的异步缓存和播放
- 视频在滑动列表中的异步缓存和播放
- 在可滑动列表(ListView & RecyclerView)中实现视频播放
- Android仿微博实现列表滑动播放/暂停视频
- (更新版)Android VideoPlayer 在滚动列表实现item视频播放(ListView控件和RecyclerView)
- Android 列表播放视频和浮动播放窗口
- [iOS]列表视频播放
- android hwcomposer 在视频播放中的应用
- android 仿微信滑动播放视频
- HTML5中的音频和视频播放
- Android中的多媒体音频和视频播放
- 在Word中播放Flash和视频
- 在Android中播放音频和视频
- 在Android中播放音频和视频
- 在Android中播放音频和视频
- 在Android中播放音频和视频
- android 视频的缩略图 缓存机制和 异步加载缩略图
- ios 视频播放/缓存同步
- Oracle之根据日期查询
- 在基于ZedBoard的Linux系统下添加自定义硬件IP(4) ——驱动程序和应用程序编写
- Android res文件夹下资源定义及使用
- nsdate学习
- Android的AlertDialog详解
- 视频在滑动列表中的异步缓存和播放
- 修改wireshark协议解析规则
- 使用Git GUI同步本地和远程源代码
- React-Native设置入口组件的问题,新手需注意
- JavaWeb学习总结(十二)——Session
- 字符集的不同导致内存泄露
- IP地址正则表达式
- 旋转数组中元素的查找
- (HDU 1002)A + B Problem II