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 VR Player(全景视频播放器) [8]:MediaPlayer+SurfaceView 视频播放_第1张图片
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


结果及源码

Android VR Player(全景视频播放器) [8]:MediaPlayer+SurfaceView 视频播放_第2张图片
测试源码:
链接: https://pan.baidu.com/s/1skMohu1 密码: yc9k

更多相关文章

  1. android 使用代码方式创建自定义progressBar——自定义控件学习(
  2. android八种通信方式
  3. android studio 更改快捷键为eclipse中习惯的方式
  4. android studio 设置编译apk的名称以及配置签名,打包方式
  5. Android中BindService方式使用的理解
  6. 简单实现Android AudioReccord录音方式
  7. android操作XML的几种方式
  8. 【Android UI设计与开发】第14期:顶部标题栏(五)两种方式实现仿微信
  9. Qt_Qtopia与Android的进程间通讯方式

随机推荐

  1. android读取扫码模组数据
  2. Android(安卓)特色开发,基于位置的服务
  3. Android 音频处理专题(播放音乐,音频捕获,
  4. Android(安卓)的属性动画的实现和使用详
  5. Android平台介绍
  6. 【Android通过手势实现的缩放处理】
  7. Android(安卓)---Application 开发中共享
  8. eclipse / ADT(Android(安卓)Develop Tool
  9. android数据库中存取图片
  10. Android androidkickstartr maven 出错