Facebook:
Instagram:
Magisto
这篇文章里的技术是基于VideoPlayerManager这个开源类库的。
类库包含所有的代码以及一个示例。我在这篇文章里会跳过一些东西,所以如果要搞清楚某个细节,那最好还是把源码导入IDE然后再看这篇文章吧。就算你不看源码,这篇文章还是可以让你理解我以何种方式解决了什么问题。
两个问题
要实现目标我们要解决两个问题:
- 我们要控制视频播放。在Android系统中我们可以使用MediaPlayer.class操作SurfaceView而且播放视频。但这有很多缺陷。我们不能再list中使用VideoView,因为VideoView继承SurfaceView,而SurfaceView不支持UI同步缓冲(UI synchronization buffer),这导致当滑动list时视频会跟进度。TextureView支持同步缓冲,但没有基于TextureView的VideoView,所以我们需要一个继承TextureView而可以操作Android MediaPlayer的View。MediaPlayer中几乎所有的操作(prepare, start, stop等等)基本上都直接调用了操作硬件的底层方法。硬件操作起来比较棘手,尤其是当某个操作耗时16毫秒以上时会进入lagging list(龟速操作表),所以我们需要在后台线程中调用这些方法。
- 我们还要知道当用户滑动的时候哪个View处在活动状态。所以我们需要追踪滑动操作并随时操作可见度最高的View。
控制视频播放
现在要提供下述功能:
假设视频正在播放,用户滑动了列表,导致另一个View可见度更高,此时要终止现有的视频播放并播放新的View中的视频。
所以主要的功能就是:停止现有播放,并在停止完成后开始新的播放。
下面是一个样例:当你点击一个视频时,正在播放的视频停止,新的视频开始播放。