问题定义
最近在做视频播放器相关的开发,想要达到的一个目标是,利用原生的播放器组件实现在线视频的播放。在做了一番探索后,我完成了两套视频播放器的组件,均支持自定义播放界面的UI。其中一套是基于Android系统原生的MediaPlayer和VideoView,另一套是基于vitamio,这两套组件支持的视频格式是不相同的,而我做的工作是将其组件化,增加了可以支持自定义UI的特性。
原生VideoView实际上是将一个MediaPlayer和一个操作栏相结合,增加了一系列视频播放控制的操作而实现。其中,VideoView的视频控制栏的UI是Framework层实现的,用户无法进行自定义的布局。关于这一点可以参考这篇文章:Android Framework中的PolicyManager简介。因此,需要寻找一种办法,实现自定义UI的特性。
探索基础
首先第一步要做的就是将原生VideoView中利用Framework层实现的UI布局部分替换成自己的实现方案。在这一部分,我参考了这篇文章:
Custom Android media controller
通过以上这篇文章的步骤,我们可以得到一个通过布局文件生成的播放器控制栏。这样就为自定义的UI实现了可能。
我所做的封装和改进
我做的就是在上面这个库的基础上,将通过布局文件生成控制栏的功能进行了进一步的封装,改进成了一个比较容易、灵活的支持自定义UI的组件。我做了如下事情:
1. 将生成UI的过程从MeidaController中抽离出来
Chris的框架中,自定义UI的部分是在MediaController中生成的,并且该UI生成部分是和MediaControler的其他控制逻辑混在一起的,没有做到很好的解耦。我们在实际开发中,不可能专门重写这样一个完整的MediaController,尤其是在除UI部分以外其他视频控制功能上完全一致的前提下。于是我将这一部分抽离出来,只提供一个给MediaController进行UI绑定的接口出来。
|
|
如上所示,我增加了一个MediaControllerGenerator接口,用来实现自定义UI的生成。我们只要在用到视频播放器的时候实现这个接口,通过generateMediaController()方法生成一个控制栏控件的集合,MediaController就可以自动将控制功能和自定义的UI布局实现绑定。
2. 封装了一个播放控制控件的集合
我们所开发的视频播放器,一把都会有开始暂停按钮、下一个视频、上一个视频、全屏、取消全屏等等的控制按钮。为了在自定义这些控件时更方便,我封装了一个自定义控件集合类BaseMediaControllerHolder,包含了所有可能用到的播放控件。
|
|
当我们自定义MediaControllerGenerator接口的实现时,生成的也是这样一个控件集合类的对象。这样一来,我们所要做的工作就变成了,从自定义的xml布局文件中生成一系列控件,然后将这些控件封装在一起生成一个BaseMediaControllerHolder类,将这个类与MediaController绑定即可。
3. 在Activity中的应用
至此,我们已经实现了一个自定义UI的MediaController,接下来只要再实现MediaPlayer和该MediaController绑定就可以了,而这个绑定过程其实也就是原生MediaPlayer的使用方法,也就变得顺理成章了。该组件可以在我的Github上查看:
Anchorer/NativeVideoPlayerComponent
其中,MediaPlayer的其他必需的控制操作,我专门实现了一个BaseNativeVideoPlayerActivity的基类Activity,我们只要继承这个Activity实现自己的视频播放Activity即可。
关于该组件的具体使用方法,可以参考example中的Demo。
不足与改进
如果你做过基于Android原生视频播放器的相关开发,你就会了解,Android原生的视频播放器支持的视频格式是非常有限的。(可以参考:Supported Media Formats)
为了对各种类型的视频做一些支持,需要在此基础上多做一些工作。实际上,这就是vitamio所做的。我完成的第二套播放器的组件,也是在vitamio的基础上,增加了自己实现的一个自定义UI的特性。