MediaPlayer

1、概念

MediaPlayer是Android原生的多媒体播放器,可以用它来实现本地或者在线音视频的播放。

2、MediaPlayer的状态

下面的图是官方给出的状态转换图,也可易理解为MediaPlayer的生命周期。

  • 椭圆形:表示MediaPlayer的状态;
  • 弧形:表示驱动对象状态转换的控制操作,有两种类型的弧,具有单箭头的弧表示同步方法调用,而具有双箭头的弧表示异步方法调用。

MediaPlayer_第1张图片

MediaPlayer状态转换说明:

  • Idle状态:当新建对象或者在对象创建之后调用reset()时,MediaPlayer对象处于Idle状态。

  • End状态:Idle状态下,调用方法release()会直接进入End状态。MediaPlayer对象处于End状态,就无法再使用它,也无法将其恢复为其他任何状态。

生命周期开始 : 进入 Idle (闲置) 状态;
生命周期结束 : 进入 End (结束) 状态;

  • Initialized状态:Idle状态下,调用setDataSource()设置视频资源,正常情况下MediaPlayer对象会进入Initialized状态。如果调用setDataSource()方法的时候,MediaPlayer对象不是处于Idle状态就会抛出异常IllegalStateException。

  • Error状态:如果设置了回调setOnErrorListener(),此时遇到音频/视频格式不支持的,分辨率太高,流式传输超时等问题时,会回调onError()方法,此时进入Error状态。可以使用 reset() 方法进入Idle 状态。

  • Prepared状态:Initialized状态下,调用prepared()方法或preparedAsync()方法进入Prepared状态。prepared()方法直接进入Parpared状态,preparedAsync()方法是异步执行,会先进入Preparing状态,播放引擎准备完毕后会通过OnPreparedListener.onPrepared()回调方法通知进入Prepared状态。
    只有在 Initialized状态下才能调用 prepare() 和 prepareAsync()方法, 在其它状态下调用就会抛出异常IllegalStateException。

创建 MediaPlayer : 通过 new MediaPlayer() 创建的对象处于Idle (闲置) 状态;
重载 MediaPlayer : 通过 create() 方法创建的 MediaPlayer 对象处于Prepare (准备) 状态;
因此使用create() 方法创建后不需要在调用prepared()方法或preparedAsync()方法,否则会报错。

  • Started状态:Prepared状态下,调用start()方法进入Started()状态。isPlaying()可以测试MediaPlayer对象是否处于Started状态。在Started状态时,可以通过setOnBufferingUpdateListener()在其OnBufferingUpdateListener.onBufferingUpdate()回调中对流播放缓冲的状态进行追踪,可以做加载进度显示。

  • Pause状态:Started状态下,调用 pause()暂停,MediaPlayer对象将进入Pause状态。调用start()方法重新进入Started状态,继续播放。pause()和start()方法是成对的。

  • Stopped状态:在Started状态时,调用stop()方法会使MdiaPlayer从Started、Paused、Prepared、PlaybackCompleted等状态进入到Stoped状态,播放停止。处于Stopped状态,就无法开始播放,直到调用prepare()或prepareAsync()将MediaPlayer对象重新设置为Prepared状态。

  • PlaybackCompleted状态:当视频播放完成之后,如果设置setLooping()为false,并且设置了回调setOnCompletionListener(),会执行OnCompletion.onCompletion()方法,在回调后进入PlaybackCompleted状态。在此状态里可以调用start()方法重新进入Started状态。
    如果设置setLooping()为true,开启了循环模式,播放完毕之后MediaPlayer会重新进入Started状态。

3、MediaPlayer回调接口

  • OnBufferingUpdateListener
    该接口的作用是在流媒体缓冲状态发生改变的时候回调,percent表示已经缓冲了的或者播放了的媒体流百分比。
mPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
    @Override
    public void onBufferingUpdate(MediaPlayer mp, int percent) {
        mBufferPercentage = percent;
    }
}
  • OnCompletionListener
    在媒体流播放完毕之后回调。可以在该回调中设置播放下一个视频文件。
mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
     @Override
    public void onCompletion(MediaPlayer mp) {        
    }
}
  • OnErrorListener
    在异步操作中出现错误时会回调该方法, 其它情况下出现错误时直接抛出异常。
    what:出现的错误类型。
    extra:针对与具体错误的附加码, 用于定位错误更详细信息。
mPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        return false;
    }
}
  • OnInfoListener
    该方法在媒体播放时出现信息或者警告时回调该方法。
    what:信息或者警告的类型。
    extra:信息或者警告的附加码,关于警告更详细信息。
mGamePlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
    @Override
    public boolean onInfo(MediaPlayer mp, int what, int extra) {
        return false;
    }
}
  • OnPreparedListener
    该方法在进入Prepared状态并开始播放的时候回调。
mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        //这里可以调用start()方法开始播放视频      
        mPlayer.start(); 
    }
}
  • OnSeekCompleteListener
    查找操作完成的时候回调该方法。
mPlayer.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
    @Override
    public void onSeekComplete(MediaPlayer mediaPlayer) {
    }
}
  • OnVideSizeChangedListener
    当视频大小首次加载的时候及视频大小更新时回调该方法,如果没有视频返回0。
mPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
    @Override
    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {        
    }
}

4、MediaPlayer常用函数

  • seekTo()
    调整播放位置可以通过seekTo()方法,由于seekTo()是异步的,实际上查找需要一定时间才能完成,实际的查找位置完成时会走setOnSeekCompleteListener()的OnSeekComplete.onSeekComplete()回调。
    seekTo()在Prepared,Paused和PlaybackCompleted 状态下执行仍然会保持当前的状态。

  • setDataSource():设置数据源,正常调用后会进入Initialized状态。

  • setAudioStreamType():设置音频流类型,设置方式如下。

mGamePlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
  • setDisplay(): 设置播放视频的SurfaceHolder,设置方式如下,使用SurfaceView播放的时候使用该方法。
SurfaceView surfaceView = findViewById(R.id.surfaceView);
SurfaceHolder surfaceHolder = surfaceView.getHolder()
mPlayer.setDisplay(surfaceHolder);
  • setSurface(): 设置播放视频的Surface,设置方式如下,需要在SurfaceTexture准备就绪onSurfaceTextureAvailable回调的时候设置,使用TextureView播放的时候使用该方法。
mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        // SurfaceTexture准备就绪
        mPlayer.setSurface(new Surface(surface));
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
        // SurfaceTexture缓冲大小变化
    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        // SurfaceTexture即将被销毁
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
        // SurfaceTexture通过updateImage更新
    }
});
  • setVolume(): 设置音量。

  • getCurrentPosition():获取当前播放器播放的位置,返回值是已经播放了的毫秒数。

  • getDuration():获取文件的播放时长 (毫秒),如果没有可用的时长,就会返回 -1。

参考文章:
用MediaPlayer+TextureView封装一个完美实现全屏、小窗口的视频播放器
MediaPlayer+TextureView实现视频播放器
【Android 多媒体开发】 MediaPlayer 状态机 接口 方法 解析

你可能感兴趣的:(Android,-,音视频,java,开发语言)