MediaPlayer
Android的音频/视频播放过程也就是MediaPlayer对象的状态转换过程。MediaPlayer的状态切换有同步操作和异步操作两种。
1. MediaPlayer对象的常用方法
getCurrentPosition()
getDruation()
getVideoWidth()
getVideoHeight()
setAudioStreamType()
setLooping()
setVolume()
pause()
start()
stop()
seekTo()
prepare()
prepareAsync()
2. MediaPlaye对象的创建与销毁
new操作符创建MediaPlayer对象,处于idle(闲置)状态。处于idle状态的MediaPlayer没有设置数据源,无法获取多媒体相关(时长、视频高度等)信息。刚创建的idle状态MediaPlayer对象在调用“1.”中方法时,底层系统无法调用MediaPlayer注册的OnErrorListener,MediaPlayer状态不受影响。
create()方法创建MediaPlayer对象,系统根据参数资源ID调用setDataSource()和prepare()方法,对象处于prepared(预备)状态。当对象在调用reset()方法后进入idle状态,此时调用“1.”中方法底层系统将调用OnErrorListener.onError()方法,MediaPlayer对象进入error状态。
MediaPlayer对象调用release()方法可进入end状态,此方法结束对象的生命周期,对象消亡。
结论: 不需要的MediaPlayer对象一定要调用release()方法以释放资源,否则其新创建的MediaPlayer对象将无法使用唯一资源,甚至创建失败。
3. 初始化
播放音频/视频前要初始化MediaPlayer:
(1)调用重载的setDataSource()方法,MediaPlayer对象进入到initialized状态
(2)调用prepare()/prepareAsync()方法,MediaPlayer对象进入到prepared状态。
prepareAsync()方式为异步调用,因此通常为MediaPlayer注册OnPreparedListener(),并在onPrepare()方法中启动播放器。当MediaPlayer对象处于prepared状态时,可以调用相关方法利用获取的多媒体信息设置播放器属性。如调用setVolume(float
leftVolume, float rightVolume)设置播放器的音量等。
4. MediaPlaye对象的操作
(1)播放、暂停、停止
调用start()方法进入到started状态(可以由isPlaying()方法进行判断)。
pause()方法使对象进入paused状态。由于started到paused间的状态转换是异步过程,会出现状态更新的延迟,此时调用isPlaying()方法辩别播放器状态会出现误差。
stop()方法使对象进入stopped状态,此时必须再次调用prepare()/prepareAsyn()才能使其进入到prepared状态实现多媒体文件播放。
onBufferingUpdateListener.onBufferingUpdate(MediaPlayer mp,int percent)方法可以对网络多媒体文件的缓冲进度进行监听,percent[0~100](int)表示多媒体数据已完成的缓冲百分比。
(2)快进、快退
seekTo()方法可以调整对象的媒体时间,实现快退、快进功能。seekTo()方法是异步的过程,媒体时间的调整的效果也可能会出现延迟。seekTo()在started、paused、prepared、playbackCompleted的状态下均可调用。
为MediaPlayer设置onSeekCompleteListener监听时,onSeekComplete()方法将被调用。
(3)播放结束状态
,MediaPlayer可能进入两种可能的状态。
当循环播放模式设置为true时,播放自然结束,MediaPlayer对象保持started状态不变
当循环播放模式设置为false时,播放自然结束,MediaPlayer对象的onCompletionListener.onCompletion()方法会被调用,MediaPlayer对象进入到playbackCompleted状态,此时调用start()方法,可重新播放音/视频文件。
播放器结束时仍可通过调用getDuration()、getVideoWidth()和getVideoHeight()等方法获取音/视频时长、视频尺寸等信息。
5. 异常的处理与抛出
播放器播放音/视频文件时,可能发生诸如I/O、多媒体文件格式等错误。MediaPlayer对象注册onErrorListener监听器,调用onErrorListener.onError()方法进行处理,对象进入到error状态后可调用reset()方法进入到idle状态以恢复播放器的状态。
方法的调用时间不合理时会抛出IllegalStateException异常,可在程序中应该使用try/catch块捕获到此类的编程错误。
myBtn1.setOnClickListener(new ImageButton.OnClickListener(){
@Override
public void onClick(View v) {try {
if(mp != null)
{ mp.stop(); }mp.prepare();
mp.seekTo(0);
mp.start();
tv.setText("音乐播放中...");
} catch (Exception e) {
tv.setText("播放发生异常...");
e.printStackTrace();
}
}
} );myBtn2.setOnClickListener(new ImageButton.OnClickListener(){
@Override
public void onClick(View v) {
try {
if(mp !=null)
{
if(isPaused){
mp.start();
isPaused=!isPaused;
tv.setText("音乐播放...");
}
else{
mp.pause();
isPaused=!isPaused;
tv.setText("音乐暂停播放...");
}
}
} catch (Exception e) {
tv.setText("音乐暂停发生异常...");
e.printStackTrace();
} }
});myBtn.setOnClickListener(new ImageButton.OnClickListener(){
@Override
public void onClick(View v) {
try {
if(mp !=null)
{
// if(isPaused==false)
// {
// mp.stop();
// isPaused=true;
// tv.setText("停止播放!");
// }
// else if(isPaused==true)
// {
// mp.start();
// isPaused = false;
// tv.setText("开始播发!");
// }
mp.stop();
mp.prepare();
mp.seekTo(0);
tv.setText("停止播放!");
}
} catch (Exception e) {
tv.setText("发生异常...");
e.printStackTrace();
}
}