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

更多相关文章

  1. 箭头函数的基础使用
  2. NPM 和webpack 的基础使用
  3. Python list sort方法的具体使用
  4. 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程
  5. Android中使用ormlite实现持久化--HelloOrmLite
  6. android APN的打开与关闭
  7. SurfaceView 的基本使用
  8. android 内存消耗分析
  9. Android中使用ViewPager制作广告栏滚屏效果

随机推荐

  1. android 指南针
  2. MTK Android(安卓)P(9.0) userdebug版本
  3. Anubis,一个支持Android(安卓)apk(Androi
  4. How to Enable USB Debugging Mode on An
  5. android 涂鸦
  6. Android(安卓)Http网络数据传输备忘
  7. Android中通过当前经纬度获得城市
  8. Appium AndroidKeyCode
  9. 【Android】动态注册广播接收器
  10. Android中ScrollView中嵌套RecyclerView