原生VideoView使用总结
Android 上原生的控件 VideoView 当然是做视频播放的首选,使用简单,下面介绍一下自己在项目使用过程中的一些注意点.
宽高问题.
- 由
VideoView的源码可知,不管你设置的View的宽高是多少,VideoView会根据视频文件的宽高重新设置View的宽高,最终显示效果类似于ImageView的FIT_CENTER. - 如果想自定义宽高,做到
FIT_XY的效果,就需要继承VideoView重写onMeasure方法.
- 由
播放和暂停/恢复.
播放调用
setVideoPath()或setVideoURI()即可,VideoView会异步加载视频,加载完毕回调OnPreparedListener().如果播放本地视频,放进raw文件夹,如video_guide.mp4.mVideoView.setVideoPath("android.resource://" + getPackageName() + "/raw/video_guide"); mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mp.start(); } }暂停:
pause().恢复:
start().注意这里不要调用resume().
进度条.
进度检测
UI中一般会有一个
SeekBar来显示当前播放进度,这里我采取是定时刷新的的办法:1.在
OnPreparedListener()中设置SeekBar的 max 值.mSeekBar.setMax(mp.getDuration());2.通过
Handler每秒计算SeekBar的位置.mSeekBar.setProgress(mVideoView.getCurrentPosition()).进度条拖动,必然是通过
OnSeekBarChangeListener()监控.mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { //建议在这里更新显示当前拖动的时间 } @Override public void onStartTrackingTouch(SeekBar seekBar) { //建议在这里(开始拖动时)停止倒计时 } @Override public void onStopTrackingTouch(SeekBar seekBar) { //建议在这里(停止拖动时)将 VideoView seekTo 当前位置. } }); 同时在 `OnPreparedListener()` 中, 为 `MediaPlayer` 设置 `OnSeekCompleteListener()` 来监听滑动停止. mp.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() { @Override public void onSeekComplete(MediaPlayer mp) { //同时开始倒计时 mVideoView.start(); } });
显示和隐藏 Loading 图.
如果播放网络视频,难免会遇到缓冲的情况,除了视频需要切片之外,客户端还需要监听缓冲状态以显示/隐藏 Loading 图.
mp.setOnInfoListener(new MediaPlayer.OnInfoListener() { @Override public boolean onInfo(MediaPlayer mp, int what, int extra) { switch (what) { case MediaPlayer.MEDIA_INFO_BUFFERING_START: //显示 Loading 图 break; case MediaPlayer.MEDIA_INFO_BUFFERING_END: //隐藏 Loading 图 break; } return false; } });“无法加载此视频”的提示.
如果是一个无法播放的视频,会弹出一个”无法播放此视频”的 Dialog. 从体验的角度来说就算无法播放也不能用这样的 Dialog 来提示,查看源码可知, 只需要为
VideoView设置OnErrorListener()即可.横竖屏切换.
视频当然是全屏播放最好,此时就需要将
Activity变为横屏.在
AndroidManifest.xml设置当前Activity的configChanges属性.android:configChanges="orientation通过代码改变当前
Activity的横竖屏.//横屏activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); //竖屏activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);在
View或Activity的onConfigurationChanged()回调中处理横竖屏切换.@Override protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { //横屏 } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { //竖屏 } }
切换后台或打开新页面(即经过
Activity的onStop()生命周期.因为
VideoView继承了SurfaceView, 在Activity的onStop()生命周期中会调用surfaceDestroyed(), 此时会释放MediaPlayer, 所以当切换后台或打开新页面回来,视频就会重头播放,暂时还没想到解决办法.
以上就是关于原生 VideoView 的简单使用, 下一步我考虑切换到 Google 的 ExoPlayer , 如果使用顺利我会继续总结.