Android(安卓)VR Player(全景视频播放器) [8]:MediaPlayer+SurfaceView 视频播放
Android VR Player(全景视频播放器) [8]:MediaPlayer+SurfaceView 视频播放
Android中播放视频一般有三种实现方式,第一种是调用其他视频播放应用;第二种是使用系统Android封装的VideoView;第三种使用MediaPlayer和SurfaceView。第一种方式当然是最简单的,两句话就搞定;第二种方式和第三种方式实质是一样的,VideoView就是系统利用MediaPlayer和SurfaceView封装的一个视频播放类,一般的视频播放的话,用这个就可以了;第三种方式稍微复杂些,不过也是最自由的。本篇博客将分享如何使用MediaPlayer和SurfaceView来实现本地视频的播放,并为视频播放添加一些播放控制。全景视频的播放同样用到MediaPlayer和“SurfaceView”,不过这里的“SurfaceView”是继承自SurfaceView的GLSurfaceView,它的使用也远远比SurfaceView复杂,所以这部分我们暂且不表,先利用本篇博客的例子熟悉一下MediaPlayer和SurfaceView。
准备布局
<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.renkangchen.surfaceviewplayertest.MainActivity"> <SurfaceView android:id="@+id/mysurfaceview" android:layout_height="match_parent" android:layout_width="match_parent"/>FrameLayout>
布局很简单,添加一个SurfaceView控件即可,为了控制视频播放,还可以添加相应的播放(暂停)按钮,进度条之类的控件。视频播放控制会在后面的博文中分享。
使用MediaPlayer+SurfaceView播放视频
提到MediaPlayer,就不得不“祭”出这张图了:
Android开发者官网的这张图很清晰地展示了MediaPlayer的生命周期,这是使用MediaPlayer时经常需要参考的一张图。生命周期控制得不好的话,很容易会出现各种bug。使用
MediaPlayer myMediaPlayer = new MediaPlayer();
来获得一个MediaPlayer的实例,还可以使用静态方法create来创建实例,两种方法的差异在于:create方法中直接指定了要播放的文件,不需要使用 setDataSource来设置,也不需要使用prepare()或者prepareAsync()来进入prepare状态。
这里我使用了默认构造方法来获得实例,所以还需要使用:
Uri videoUri = Uri.parse("http:/XXXXX/sample.mp4"); try { myMediaPlayer.setDataSource(MainActivity.this, videoUri); myMediaPlayer.prepareAsync(); }catch(Exception e) { e.printStackTrace();}
这样的方法来设置要播放的资源并异步进行播放器准备。
如果播放器没有准备好就直接开始播放,会出现播放器错误,那么如何知道播放器是否准备好呢?
myMediaPlayer.setOnPreparedListener(this);
给播放器添加上准备完成监听,然后在回调函数中做播放处理就可以了:
@Override public void onPrepared(MediaPlayer mp) { myMediaPlayer.start(); ... }
不再使用时,记得释放MediaPlayer:
if(null != myMediaPlayer ) myMediaPlayer.release(); myMediaPlayer = null; }
所以MediaPlayer的使用流程为:创建实例,设置资源,就绪,播放,释放。
SurfaceView和一般的View的区别在于SurfaceView允许在非UI线程改变其内容,而一般的View不可以。因为SurfaceView可能在Activity的OnDestroy()之前被销毁,所以需要对此作处理。
SurfaceView使用SurfaceHolder来进行管理,
SurfaceHolder mySurfaceHolder = mySurfaceview.getHolder();
接着对SurfaceHolder添加回调addCallback,
mySurfaceHolder.addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder surfaceHolder) { Uri videoUri = Uri.parse("http:/XXXXX/sample.mp4"); try { myMediaPlayer.setDataSource(MainActivity.this, videoUri); myMediaPlayer.prepareAsync(); }catch(Exception e) { e.printStackTrace(); } } @Override public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) { } @Override public void surfaceDestroyed(SurfaceHolder surfaceHolder) { if(null != myMediaPlayer ) myMediaPlayer.release(); myMediaPlayer = null; } }); }
surfaceCreated在surface创建时调用,我们把MediaPlayer的“准备工作放在这里”;surfaceChanged在surface尺寸变化时调用;surfaceDestroyed在surface被销毁时调用,我们在这里释放MediaPlayer。
完成了上述的工作,只需要修改MediaPlayer的Prepared回调
@Override
public void onPrepared(MediaPlayer mp) {
myMediaPlayer.start();
myMediaPlayer.setDisplay(mySurfaceHolder);
myMediaPlayer.setScreenOnWhilePlaying(true);
mySurfaceHolder.setKeepScreenOn(true);
}
通过setDisplay(mySurfaceHolder)设置显示视频到surface;setScreenOnWhilePlaying(true)设置surfaceview保持在屏幕上。
为了便于调试,也可以为MediaPlayer设置setOnErrorListener(this)来监听播放过程中出现的错误,如果播放网络视频,还可以设置setOnBufferingUpdateListener(this)来监听缓冲情况。
Reference
MediaPlayer
android视频播放(二) 利用android原生的MediaPlayer+SurfaceView
结果及源码
测试源码:
链接: https://pan.baidu.com/s/1skMohu1 密码: yc9k
更多相关文章
- 箭头函数的基础使用
- NPM 和webpack 的基础使用
- Python list sort方法的具体使用
- 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程
- Android中使用ormlite实现持久化--HelloOrmLite
- android APN的打开与关闭
- SurfaceView 的基本使用
- android 内存消耗分析
- Android中使用ViewPager制作广告栏滚屏效果