最近需要写一个关于视频播放的功能,功能很简单,就是实现简单的视频播放,暂停,和播放进度的显示,所以就不考虑使用第三方播放器来实现,经过调研决定使用android提供的videoView控件来实现。下面就写下我的使用心得:
进度显示
关于进度显示的要求是在视频右上角显示视频的倒计时时间,我最初想到的就是使用Handler的postDealyed方法去实现,后来在网上查资料发现使用新线程进行进度的更新比使用Handler的postDealyed方法更好,详细内容可以参考
强迫症的研究——MediaPlayer播放进度条的优化
视频播放的恢复
在Google的官方文档中对videoView的介绍有这样一段话:
Note: VideoView does not retain its full state when going into the background. In particular, it does not restore the current play state, play position, selected tracks, or any subtitle tracks added via [addSubtitleSource()](https://developer.android.com/reference/android/widget/VideoView.html#addSubtitleSource(java.io.InputStream, android.media.MediaFormat)). Applications should save and restore these on their own in onSaveInstanceState(Bundle) and onRestoreInstanceState(Bundle).
大概意思就是<code>videoView</code>不会为你自动保存和恢复视频播放的状态,如果需要你要自己在<code>onSaveInstanceState(Bundle)</code>和<code>onRestoreInstanceState(Bundle)</code>中进行视频播放状态的保存和恢复,所以我们要在<code>onPuse</code>方法中对<code>videoView</code>的状态进行保存,暂停视频的播放;在<code>onStop</code>方法中kill播放进度线程,在<code>onStart</code>方法中对<code>videoView</code>进行状态恢复
问题一
但是这样并没有完美的解决这个问题,当你按下home键再回到app时视频有时不会继续上次的播放而是重新从头播放。这个是因为在恢复<code>videoView</code>的时候<code>seekto</code>之后直接调用<code>videoView</code>的<code>start()</code>方法;但是<code>seekto</code>方法是一个异步方法,所以出现上面的原因你就明白了,怎么去解决呢?android提供了<code>MediaPlayer.OnSeekCompleteListener</code>;当<code>seekto</code>完成时会回调这个方法,我们可以在这个方法中调用<code>start ()</code>方法。所以,我们可以在<code>videoView</code>的onPrepared回调方法中拿到Mediaplayer并给它设置<code>OnSeekCompleteListener</code>
问题二
按下home键后再回到app时<code>seekto</code>的位置不准
这个问题经过调研和查阅资料发现android的<code>seekto</code>方法不是根据方法中的参数值来定位的,而是定位到参数值附近的关键帧,至于什么是关键帧大家可以Google,百度一下,对于这个问题目前找到的比较好的解决方法就是对视频增加关键帧,如果有其他好的解决办法欢迎告知
耳机拔出时视频暂停播放
这个肯定是要注册广播接收器了,就监听了下面两个系统广播:
1.监听<code>Intent.ACTION_HEADSET_PLUG</code>系统广播(监听有线耳机)
2.监听<code>BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED</code>系统广播(无线耳机)
但是事情总不是那么的一帆风顺,后来发现这样子有事会有延迟,至于怎么造成的我也没有查太清楚,但是找到新的替代方法:
监听<code>android.intent.action.HEADSET_PLUG</code>系统广播(监听有线,无线耳机的断开)