Android:MediaPlayter——音乐播放器

一,理论知识

椭圆-状态、单弧线-同步调用、双弧线-异步调用

一,Idle(闲置)状态

方法:新创建(new)的MediaPlayer对象  或者  任何状态调用了 reset() 方法

区别:处于Idle状态时,调用 getCurrentPosition(), getDuration(), getVideoHeight(), getVideoWidth(), setAudioStreamType(), setLooping(), setVolume(), pause(), start(), stop(), seekTo(), prepare(), prepareAsync()方法都会报错。1、通过reset()方法进入idle状态的话会触发OnErrorListener.onError(),并且MediaPlayer会进入Error状态。2、通过new()创建MediaPlayer对象,则并不会触发OnErrorListener.onError(),也不会进入Error状态。

注意:create()初始化的MediaPlayer直接进入Prepared状态

二,End(结束)状态

方法:任何状态通过release()方法

特点:

  • 调用release()后只能进入End状态,一旦进入End状态,就没法迁移到其他状态。
  • MediaPlayer不再被使用时,应立即调用release()方法来释放资源,资源可能包括硬件加速组件的单态固件,若没有调用release()方法可能会导致之后的MediaPlayer对象实例无法使用这种单态硬件资源,导致异常。

三,Error(错误状态)

方法:回调OnErrorListener.onError()方法

特点:

  • 不支持的格式/分辨率太高/流超时等,还有编程错误(比如在无效状态下调用某个操作)等错误操作进入Error状态。
  • 一旦发生错误,MediaPlayer对象会进入Error状态,此时可以调用reset()方法把这个对象恢复到Idle状态。
  • MediaPlayer进入Error状态,及时捕捉并妥善处理Error可以帮助我们及时释放相关的软硬件资源,改善用户体验。

四,Initialized(初始化)状态

方法:Idle 状态调用 setDataSource() 方法

特点:

  • 表示要播放的文件已经设置好了
  • 非Idle状态下调用此方法会报 ILlegalStateException异常。setDataSource()方法可能会抛出IOException异常。

五,Prepared(就绪)和Preparing(准备中)状态

方法:调用prepare()方法——同步,调用prepareAsync()方法——异步

特点:

  • 异步的prepareAsync()方法需要通过OnPrepareListener.onPrepared()监听准备是否完成。
  • 在不合适的状态下调用prepare()和prepareAsync()方法会抛出ILlegalStateException异常。
  • 只有进入prepare状态才表明到目前为止都没有错误,可以进行文件播放。

注意:create()初始化的MediaPlayer直接进入Prepared状态

六,Started(开始)状态

方法:调用start()方法

特点:

  • isPlaying()测试MediaPlayer是否处于Started状态
  • OnBufferingUpdateListener.onBufferingUpdate() 方法, 可以获取视频音频流的缓冲状态。
  • Started状态下调用start()方法没有影响。

七,Paused(暂停)状态

方法:调用pause()方法

特点:

  • Paused状态下调用pause()方法没有影响。
  • Paused状态调用start()进入Started状态。
  • Paused状态调用seekTo()仍然是Paused()
  • Started与Paused状态的转换在内部的播放引擎中是异步的,所以isPlaying()可能会延时更新,如果是播放网络流媒体,这个延时可能会有几秒。

八,Stop(停止)状态

方法:除了Idle、Initialized状态,其它状态下都可以调用stop()迁移到Stopped状态。

特点:

  • Stopped状态下调用stop()方法没有影响。
  • Stop状态不能直接start(),要回到prepared状态(prepare()或prepareAsyn()),才能start。

九,seekTo()播放位置调整

seekTo() 方法: 该方法异步, 调用后 播放器引擎还需要进行其它操作, 跳转才能完成;

进行的操作:播seekTo()方法可以调整播放位置,播放网络流媒体时延时很明显。实际定位完成后,通过OnSeekComplete.onSeekComplete()通知。

获取播放位置: 调用 getCurrentPosition() 方法, 可以获取当前播放的位置, 可以帮助播放器更新进度条;

对象:“活动状态”(Prepared、Started、Paused、PlaybackCompleted状态)下都可以调用seekTo()方法。

十,PlaybackCompleted (播放完毕) 状态

方法:如果通过setLooping()方法开启了循环模式,会重新进入到Started状态,并且不会回调OnCompletion.onCompletion()方法、如果没有开启循环,就会回调这个方法。

特点:PlaybackCompleted状态下调用start()方法会迁移到Started状态。

状态汇总

方法 有效状态 调用结果 无效状态
setDataSource() Idle 调用成功,会迁移到Initialized状态 报IllegalStateException异常
prepare()、prepareAsync() Initialized/Stopped 调用成功,会迁移到Prepared/Preparing状态 报IllegalStateException异常
pause() Started/Paused 调用成功,会迁移到Paused状态 player进入Error状态
start() Prepared/Started/Paused/PlaybackCompleted 调用成功,会迁移到Started状态 player进入Error状态
stop() Prepared/Started/Stopped/Paused/PlaybackCompleted 调用成功,会迁移到Stopped状态 player进入Error状态
seekTo() Prepared/Started/Paused/PlaybackCompleted 调用成功,不会改变player的状态 player进入Error状态

二,实际应用

一,播放应用资源中的音乐

// 设置播放数据源
MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.gm);
// 不需要准备,create,创建完成直接可以使用播放
mediaPlayer.start();

二,播放SD卡上中的音乐(需要添加权限)

MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource("/sdcard/test.mp3");
mediaPlayer.start();
==============================================
File file =new File(Environment.getExternalStorageDirectory(),"man.mp3");
Uri uri = Uri.fromFile(file);
MediaPlayer mediaPlayer = MediaPlayer.create(this,uri);
mediaPlayer.start();

三,播放asset中的音乐

AssetFileDescriptor afd= getAssets().openFd(“rain.mp3”);
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(), afd.getLength());
mediaPlayer.start();

四,播放网络中的音乐

//本地Tomcat服务器的地址
String url="http://188.188.3.79:8080/itest/gm.mp3";
//播放,网络音乐
try {
     init();
      //初始化 http://188.188.3.79:8080/itest/gm.mp3
      mediaPlayer.reset();
      //设置资源
      mediaPlayer.setDataSource(url);
      //准备声音远程音乐
      mediaPlayer.prepareAsync();
      /** 设置监听器什么时候缓冲,准备好音乐*/
      mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
          public void onPrepared(MediaPlayer mp) {
              //开始播放
              mediaPlayer.start();
           }
       });
} catch (Exception e) {
            e.printStackTrace();
}

添加权限:

 <uses-permission android:name="android.permission.INTERNET"/>
发布了360 篇原创文章 · 获赞 163 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/qq_42192693/article/details/105062643