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"/>
上一篇: Android播放本地音乐播放器