MediaPlayer应用总结

MediaPlayer应用总结

1. MediaPlayer概述

MediaPlayer位于 android.media包中,为android平台提供了音频和视频的播放功能。MediaPlayer的底层是基于 OpenCore(PacketVideo)的库实现的,为了构建一个MediaPlayer程序,上层还包含了进程间通讯等内容,这种进程间通讯的基础 是andoid基本库中的Binder机制。

 

2. 类结构

java.lang.Object

?

android.media.MediaPlayer

 

 

 

3. 构造方法和公用方法

构造方法:

Public Constructors

 

MediaPlayer()

默认构造方法。

 

公有方法:

Public Methods

static MediaPlayer

create(Context context, Uri uri, SurfaceHolder holder)

指定从资源ID对应的资源文件中来装载音乐文件,同时指定了SurfaceHolder对象并返回MediaPlyaer对象。

static MediaPlayer

create(Context context, int resid)

指定从资源ID对应的资源文件中来装载音乐文件,并返回新创建的MediaPlyaer对象。

static MediaPlayer

create(Context context, Uri uri)

从指定Uri装在音频文件,并返回新创建的MediaPlayer对象。

int

getCurrentPosition()

获取当前播放的位置。

int

getDuration()

获取音频的时长。

int

getVideoHeight()

获取视频的高度。

int

getVideoWidth()

获取视频的宽度。

boolean

isLooping()

判断MediaPlayer是否正在循环播放。

boolean

isPlaying()

判断MediaPlayer是否正在播放。

void

pause()

暂停播放。

void

prepare()

准备播放(装载音频),调用此方法会使MediaPlayer进入Prepared状态。

void

prepareAsync()

准备播放异步音频。

void

release()

释放媒体资源。

void

reset()

重置MediaPlayer进入未初始化状态。

void

seekTo(int msec)

寻找指定的时间位置。

void

setAudioStreamType(int streamtype)

设置音频流的类型。

void

setDataSource(String path)

指定装载path路径所代表的文件。

void

setDataSource(Context context, Uri uri, Map

指定装载uri所代表的文件。

void

setDataSource(Context context, Uri uri)

指定装载uri所代表的文件。

void

setDataSource(FileDescriptor fd, long offset, long length)

指定装载fd所代表的文件中从offset开始长度为length的文件内容。

void

setDataSource(FileDescriptor fd)

指定装载fd所代表的文件。

void

setDisplay(SurfaceHolder sh)

设置显示方式。

void

setLooping(boolean looping)

设置是否循环播放。

void

setNextMediaPlayer(MediaPlayer next)

设置当前流媒体播放完毕,下一个播放的MediaPlayer

void

setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener listener)

注册一个回调函数,在网络视频流缓冲变化时调用。

void

setOnCompletionListener(MediaPlayer.OnCompletionListener listener)

Media Player的播放完成事件绑定事件监听器。

void

setOnErrorListener(MediaPlayer.OnErrorListener listener)

MediaPlayer的播放错误事件绑定事件监听器。

void

setOnPreparedListener(MediaPlayer.OnPreparedListener listener)

MediaPlayer调用prepare()方法时触发该监听器。

void

setOnSeekCompleteListener(MediaPlayer.OnSeekCompleteListener listener)

MediaPlayer调用seek()方法时触发该监听器。

void

setOnVideoSizeChangedListener(MediaPlayer.OnVideoSizeChangedListener listener)

注册一个用于监听视频大小改变的监听器。

void

setScreenOnWhilePlaying(boolean screenOn)

置是否使用SurfaceHolder来显示。

void

setSurface(Surface surface)

设置Surface

void

setVideoScalingMode(int mode)

设置视频缩放的模式。

void

setVolume(float leftVolume, float rightVolume)

设置播放器的音量。

void

setWakeMode(Context context, int mode)

MediaPlayer设置低级电源管理行为。.

void

start()

开始或恢复播放。

void

stop()

停止播放。

 

 

 

 

4. 常用方法分析

1) 如何获得MediaPlayer实例:

可以使用直接new的方式:MediaPlayermp = new MediaPlayer();也可以使用create的方式,如:MediaPlayer mp = MediaPlayer.create(this, R.raw.test);//这时就不用调用setDataSource

 

2) 如何设置要播放的文件:

MediaPlayer要播放的文件主要包括3个来源:

a. 用户在应用中事先自带的resource资源 例如:MediaPlayer.create(this, R.raw.test);

b. 存储在SD卡或其他文件路径下的媒体文件 例如:mp.setDataSource("/sdcard/test.mp3");

c. 网络上的媒体文件  

例如:mp.setDataSource("http://www.citynorth.cn/music/confucius.mp3");

d. 以file://开头的本地文件URI和以URL为地址的网络文件URI

e. MediaPlayer 的setDataSource总共有四个方法:

setDataSource (String path);

setDataSource (FileDescriptor fd);

setDataSource (Context context, Uri uri);

setDataSource (FileDescriptor fd, long offset, long length);

 

3) 对播放器的主要控制方法:

Android通过控制播放器的状态的方式来控制媒体文件的播放,其中:

prepare()prepareAsync() 提供了同步和异步两种方式设置播放器进入prepare状态,需要注意的是,如果MediaPlayer实例是由create方法创建的,那么第一次启动播放前不需要再调用prepare()了,因为create方法里已经调用过了。

start()是真正启动文件播放的方法,

pause()stop()比较简单,起到暂停和停止播放的作用,

seekTo()是定位方法,可以让播放器从指定的位置开始播放,需要注意的是该方法是个异步方法,也就是说该方法返回时并不意味着定位完成,尤其是播放的网络文件,真正定位完成时会触发OnSeekComplete.onSeekComplete(),如果需要是可以调用setOnSeekCompleteListener(OnSeekCompleteListener)设置监听器来处理的。

release()可以释放播放器占用的资源,一旦确定不再使用播放器时应当尽早调用它释放资源。

reset()可以使播放器从Error状态中恢复过来,重新会到Idle状态。

 

4) 播放状态方法:

getCurrentPosition:得到当前播放位置

getDuration:    得到文件的时间

setAudioStreamType:    设置流媒体的类型

setDisplay:        设置用SurfaceHolder来显示多媒体

setOnVideoSizeChangedListener:视频尺寸监听

setScreenOnWhilePlaying:        设置是否使用SurfaceHolder来显示

 

5) 与MediaPlayer有关的事件监听器:

MediaPlayer提供了一些绑定事件监听器的方法,用于监听MediaPlayer播放过程中所发生的特定事件,绑定事件监听器的方法如下:

u setOnCompletionListener(MediaPlayer.OnCompletionListener listener):为 Media Player的播放完成事件绑定事件监听器。

u setOnErrorListener(MediaPlayer.OnErrorListener listener):为MediaPlayer的播放错误事件绑定事件监听器。

u setOnPreparedListener(MediaPlayer.OnPreparedListener listener):当 MediaPlayer调用prepare()方法时触发该监听器。

u setOnSeekCompleteListener(MediaPlayer.OnSeekCompleteListener listener):当MediaPlayer调用seek()方法时触发该监听器。

u setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener listener)     :   注册一个回调函数,在网络视频流缓冲变化时调用。

u setOnVideoSizeChangedListener(MediaPlayer.OnVideoSizeChangedListener listener)  注册一个用于监听视频大小改变的监听器。

u 因此可以在创建一个MediaPlayer对象之后,通过为该MediaPlayer绑定监听器来监听相应的事件,例如如下代码:

 

//为MediaPlayer的播放完成事件绑定事件监听器

mPlayer.setOnErrorListener(new OnErrorListener() {

@Override

publicboolean onError(MediaPlayer mp,int what,int extra) {

// TODO Auto-generated method stub

//针对错误进行相应的处理

// ... ...

}});

 

 

//为MediaPlayer的播放完成讲件绑定市件监听器

mPlayer.setOnCompletionListener(new OnCompletionListener() {

@Override

publicvoid onCompletion(MediaPlayer mp) {

// TODO Auto-generated method stub

current++;

prepareAndPlay(current);

}});

 

6) 使用进度条

进度条SeekBar可以用来显示播放进度,用户也可以利用SeekBar的滑块来控制音乐的播放。

 

SeekBar需要使用的一些方法:

u setProgress(int value):设置滑块的位置方法为。

u setMax(int value):设置进度条的最大长度。

u setOnSeekBarChangeListener(OnSeekBarChangeListener l):设置SeekBar的进度改变事件。

 

MusicPlayer需要使用的一些方法:

u getDuration():获得音乐长度为。

u getCurrentPosition():获得现在播放的位置。

u seekTo(int msec):调用seekTo()方法可以调整播放的位置。

seekTo(int)方法是异步执行的,所以它可以马上返回,但是实际的定位播放操作可能需要一段时间才能完成,尤其是播放流形式的音频/视频。当实际 的定位播放操作完成之后,内部的播放引擎会调用客户端程序员提供的OnSeekComplete.onSeekComplete()回调方法。可以通过 setOnSeekCompleteListener(OnSeekCompleteListener)方法注册。

seekTo(int)方法也可以在其它状态下调用,比如Prepared,Paused和PlaybackCompleted状态。此外,目前的播放位 置,实际可以调用getCurrentPosition()方法得到,它可以帮助如音乐播放器的应用程序不断更新播放进度。

 

创建并使用进度条的步骤:

 

第一步:创建一个进度条

//进度条

static SeekBarskbMusic;

skbMusic=(SeekBar)findViewById(R.id.skbMusic);

 

第二步:为进度条的改变事件注册并添加监听器

skbMusic.setOnSeekBarChangeListener(sChangeListener);

 

//SeekBar进度改变事件

OnSeekBarChangeListenersChangeListener=new OnSeekBarChangeListener() {

 

@Override

publicvoid onStopTrackingTouch(SeekBar seekBar) {

//TODO Auto-generated method stub

//当拖动停止后,控制mediaPlayer播放指定位置的音乐

MusicService.mediaPlayer.seekTo(seekBar.getProgress());

MusicService.isChanging=false;

}

 

@Override

publicvoid onStartTrackingTouch(SeekBar seekBar) {

//TODO Auto-generated method stub

MusicService.isChanging=true;

}

 

@Override

publicvoid onProgressChanged(SeekBar seekBar,int progress,boolean fromUser) {

//TODO Auto-generated method stub

}

 

};

 

第三步:设置进度条的最大长度:

//getDuration()方法要在prepare()方法之后,否则会出现Attempt to call getDuration without a valid mediaplayer异常

MusicBox.skbMusic.setMax(mediaPlayer.getDuration());//设置SeekBar的长度

 

第四步:更新进度条

//----------定时器记录播放进度---------//

 

mTimer =new Timer();

 

mTimerTask =new TimerTask() {

@Override

publicvoid run() {

isTimerRunning=true;

if(isChanging==true)//当用户正在拖动进度进度条时不处理进度条的的进度

return;

MusicBox.skbMusic.setProgress(mediaPlayer.getCurrentPosition());

}

};

 

//每隔10毫秒检测一下播放进度

mTimer.schedule(mTimerTask, 0, 10);

 

7) 装载音频文件:

为了让MediaPlayer来装载指定音频文件,MediaPlayer提供了如下简单的静态方法。

u static MediaPlayer create(Context context, Uri uri):从指定Uri来装载音频文件,并返回新创建的MediaPlayer对象。

u static MediaPlayer create(Context context, int resid):从 resid资源 ID对应的资源文件中装载音频文件,并返回新创建的MediaPlayer对象。

提示:上而这两个方法用起来非常方便,但这两个方法每次都会返回新创建的MediaPlayer对象,如来程序需要使用MediaPlayer循环播放多 个音频文件,使用MediaPlayer的静态create方法就不太合适了,此时可通过MediaPlayer的setDataSource()方法来 装载指定的音频文件。MediaPlayer提供了如下方法来指定装载相应的音频文件:

u setDataSource(String path):指定装载path路径所代表的文件。

u setDataSource(FileDescriptor fd, long offset,long length):指定装载fd所代表的文件中从offset开始长度为length的文件内容。

u setDataSource(FileDescriptor fd):指定装载fd所代表的文件。

u setDataSource(Context context, Uri uri):指定装载uri所代表的文件。

提示:执行上面所示的setDataSource()方法之后,MediaPlayer并未真正去装载那些音频文件,还需要调用MediaPlayer的prepare()方法去准备音频,所谓“准备”,就是让MediaPlayer真正去装载音频文件。

 

使用已有的MediaPlayer对象装载“一首”歌曲的代码模板为:

mPlayer.reset();

//装战下一竹歌曲

mPlayer.setDataSource(M/mnt/sdcard/next.mp3);

//准备声音 

mPlayer.prepare();

//播放

mPlayer.start();

}

 

 

 

 

 

5. MediaPlayer播放不同来源的音频文件

5.1. 播放应用的资源文件

播放应用的资源文件需要两步即:

1) 调用MediaPlayer的create(Context context,int resid)方法加指定资源文件。

2) 调用 MediaPlayer的 start()、pause()、stop()等方法控制播放即可。

例如如下代码:

MediaPlayer mPlayer=new MediaPlayer();

mPlayer.create(this, R.raw.music);

5.2. 播放应用的原始资源文件

播放应用的资源文件按如下步骤执行。

1) 调用 Context的 getAssets()方法获取应用的 AssetManager。

2) 调用AssetManager对象的openFd(String name)方法打开指定的原生资源,该方法返回一个AssetFileDescriptor对象。

3) 调用 AssetFileDescriptor的 getFileDescriptor()、getStartOffset()和 getLength()方法来获取音频文件的FileDescriptor、开始位置、长度等。

4) 创建MediaPlayer对象(或利用已有的MediaPlayer对象),并调用MediaPlayer对象的setDataSource(FileDescriptor fd,long offset, long length)方法来装载音频资源。

5) 调用MediaPlayer对象的prepare()方法准备音频。

6) 调用MediaPlayer的start()、pause()、stop()等方法控制播放即可。

 

例如如下代码片段:

//获取assets目录下指定文件的AssetFileDescriptor对象

AssetFileDescriptor assetFileDescriptor=assetManager.openFd(musics[current]);

mediaPlayer.reset();//初始化mediaPlayer对象

 

mediaPlayer.setDataSource(assetFileDescriptor.getFileDescriptor(), assetFileDescriptor.getStartOffset(), assetFileDescriptor.getLength());

 

//准备播放音乐

mediaPlayer.prepare();

//播放音乐

mediaPlayer.start();

5.3. 播放外部存储器上音频文件

播放外部存储器上音频文件按如下步骤执行。

1) 创建MediaPlayer对象(或利用已有的MediaPlayer对象),并调用MediaPlayer对象的setDateSource(String path)方法装载指定的音频文件。

2) 调用MediaPlayer对象的prepare()方法准备音频。

3) 调用MediaPlayer的start()、pause()、stop()等方法控制播放即可。

 

 

例如如下代码:

//加载SD卡上的指定资源音频文件

mPlayer.setDataSource("/mnt/You Are The One.mp3");

mPlayer.prepare();//准备因音频

mPlayer.start();//播放音频

5.4. 播放来自网络的音频文件

播放来自网络的音频文件冇两种方式:

1) 直接使用MediaPlayer的静态create(Context context, Uri uri)方法;

2) 调用 MediaPlayer的setDataSource(Context context,Uri uri)装载指定Uri对应的音频文件。

 

以第二种方式播放来自网络的音频文件的步骤如下:

a. 根据网络上的音频文件所在的位置创建Uri对象。

b. 创建MediaPlayer对象(或利用己有的MediaPlayer对象),并调用MediaPlayer对象的 setDateSource(Context context,Uri uri)方法装载Uri对应的音频文件。

c. 调用MediaPlayer对象的prepare()方法准备音频。

d. 调用MediaPlayer的start()、pause()、stop()等方法控制播放即可。

 

例如如下代码片段:

Uri uri = Uri.parse("http://play.baidu.com/heihei.mp3");

MediaPlayer mPlayer = new MediaPlayer();

 

//使用MediaPlayer根据Uri来加载指定的声音文件

mPlayer.setDataSource(this, uri);

mPlayer.prepare();//准备因音频

mPlayer.start();//播放音频

 

MediaPlayer除了调用prepare()方法来准备声音之外,还以调用prepareAsync()来准备声音,prepareAsync()与普通prepare()方法的区别在于,prepareAsync()是异步的,它不会阻塞当前的UI线程。

6. MediaPlayer的生命周期和状态图

对播放音频/视频文件和流的控制是通过一个状态机来管理的。下图显示一个MediaPlayer对象被支持的播放控制操作驱动的生命周期和状态。椭圆代表MediaPlayer对象可能驻留的状态。弧线表示驱动MediaPlayer在各个状态之间迁移的播放控制操作。这里有两种类型的弧线。由一个箭头开始的弧代表同步的方法调用,而以双箭头开头的代表的弧线代表异步方法调用。


这张状态转换图清晰的描述了 MediaPlayer 的各个状态,也列举了主要的方法的调用时序,每种方法只能在一些特定的状态下使用,如果使用时 MediaPlayer 的状态不正确则会引发 IllegalStateException 异常 

1) Idle 状态:

当使用 new() 方法创建一个 MediaPlayer 对象或者调用了其 reset() 方法时,该 MediaPlayer 对象处于 idle 状态。这两种方法的一个重要差别就是:如果在这个状态下调用了 getDuration() 等方法(相当于调用时机不正确),通过 reset()方法进入 idle 状态的话会触发 OnErrorListener.onError() ,并且 MediaPlayer 会进入 Error 状态;如果是新创建的 MediaPlayer对象,则并不会触发 onError(), 也不会进入 Error 状态。

a. 在一个新构建的MediaPlayer对象和一个调用了reset()方法的MediaPlayer对象之间有一个微小的但是十分重要的差别。在处于Idle状态时,调用getCurrentPosition()getDuration()getVideoHeight()getVideoWidth()setAudioStreamType(int)setLooping(boolean)setVolume(float, float)pause()start()stop()seekTo(int)prepare() 或者 prepareAsync() 方法都是编程错误。当一个MediaPlayer对象刚被构建的时候,内部的播放引擎和对象的状态都没有改变,在这个时候调用以上的那些方法,框架将无法回调客户端程序注册的OnErrorListener.onError()方法;但若这个MediaPlayer对象调用了reset()方法之后,再调用以上的那些方法,内部的播放引擎就会回调客户端程序注册的OnErrorListener.onError()方法了,并将错误的状态传入。      

b. 们建议,一旦一个MediaPlayer对象不再被使用,应立即调用release()方法来释放在内部的播放引擎中与这个MediaPlayer对象关联的资源。资源可能包括如硬件加速组件的单态组件,若没有调用release()方法可能会导致之后的MediaPlayer对象实例无法使用这种单态硬件资源,从而退回到软件实现或运行失败。一旦MediaPlayer对象进入了End状态,它不能再被使用,也没有办法再迁移到其它状态。

c. 此外,使用new操作符创建的MediaPlayer对象处于Idle状态,而那些通过重载的create()便利方法创建的MediaPlayer对象却不是处于Idle状态。事实上,如果成功调用了重载的create()方法,那么这些对象已经是Prepare状态了。

 

2) End 状态:

通过 release() 方法可以进入 End 状态,只要 MediaPlayer 对象不再被使用,就应当尽快将其通过 release() 方法释放掉,以释放相关的软硬件组件资源,这其中有些资源是只有一份的(相当于临界资源)。如果 MediaPlayer 对象进入了End 状态,则不会在进入任何其他状态了。

 

3) Initialized 状态:

这个状态比较简单, MediaPlayer 调用 setDataSource() 方法就进入 Initialized 状态,表示此时要播放的文件已经设置好了

 

4) Prepared 状态: 

初始化完成之后还需要通过调用 prepare() 或 prepareAsync() 方法,这两个方法一个是同步的一个是异步的,只有进入 Prepared 状态,才表明 MediaPlayer 到目前为止都没有错误,可以进行文件播放。

 

5) Preparing 状态:

这个状态比较好理解,主要是和 prepareAsync() 配合,如果异步准备完成,会触发OnPreparedListener.onPrepared() ,进而进入 Prepared 状态

6) Started 状态:

显然, MediaPlayer 一旦准备好,就可以调用 start() 方法,这样 MediaPlayer 就处于 Started 状态,这表明 MediaPlayer 正在播放文件过程中。可以使用 isPlaying()测试 MediaPlayer 是否处于了 Started 状态。 如果播放完毕,而又设置了循环播放,则 MediaPlayer 仍然会处于 Started 状态,类似的,如果在该状态下 MediaPlayer 调用了 seekTo() 或者start() 方法均可以让 MediaPlayer 停留在 Started 状态。

 

7) Paused 状态:

Started 状态下 MediaPlayer 调用 pause() 方法可以暂停 MediaPlayer ,从而进入 Paused 状态,MediaPlayer 暂停后再次调用 start() 则可以继续 MediaPlayer 的播放,转到 Started 状态,暂停状态时可以调用 seekTo() 方法,这是不会改变状态的。

 

8) Stop 状态:

Started 或者 Paused 状态下均可调用 stop() 停止 MediaPlayer ,而处于 Stop 状态的 MediaPlayer 要想重新播放,需要通过 prepareAsync() 和 prepare() 回到先前的 Prepared 状态重新开始才可以。

 

9) PlaybackCompleted 状态:

文件正常播放完毕,而又没有设置循环播放的话就进入该状态,并会触发OnCompletionListener 的 onCompletion() 方法。此时可以调用 start() 方法重新从头播放文件,也可以 stop() 停止 MediaPlayer,或者也可以 seekTo() 来重新定位播放位置

 

10) Error 状态:

 如果由于某种原因 MediaPlayer 出现了错误,会触发 OnErrorListener.onError() 事件,此时 MediaPlayer 即进入 Error 状态,及时捕捉并妥善处理这些错误是很重要的,可以帮助我们及时释放相关的软硬件资源,也可以改善用户体验。通过 setOnErrorListener(android.media.MediaPlayer.OnErrorListener) 可以设置该监听器。如果 MediaPlayer 进入了 Error状态,可以通过调用 reset() 来恢复,使得 MediaPlayer 重新返回到 Idle 状态

 

另外一些情况:

1) 在一般情况下,由于种种原因一些播放控制操作可能会失败,如不支持的音频/视频格式,缺少隔行扫描的音频/视频,分辨率太高,流超时等原因,等等。因此,错误报告和恢复在这种情况下是非常重要的。有时,由于编程错误,在处于无效状态的情况下调用了一个播放控制操作可能发生。在所有这些错误条件下,内部的播放引擎会调用一个由客户端程序员提供的OnErrorListener.onError()方法。客户端程序员可以通过调用MediaPlayer.setOnErrorListener(android.media.MediaPlayer.OnErrorListener)方法来注册OnErrorListener.

a.  一旦发生错误,MediaPlayer对象会进入到Error状态。

b. 为了重用一个处于Error状态的MediaPlayer对象,可以调用reset()方法来把这个对象恢复成Idle状态。

c. 注册一个OnErrorListener来获知内部播放引擎发生的错误是好的编程习惯。

d. 在不合法的状态下调用一些方法,如prepare()prepareAsync()setDataSource()方法会抛出IllegalStateException异常。

 

2) 调用setDataSource(FileDescriptor)方法,或setDataSource(String)方法,或setDataSource(Context,Uri)方法,或setDataSource(FileDescriptor,long,long)方法会使处于Idle状态的对象迁移到Initialized状态。

a. 若当此MediaPlayer处于其它的状态下,调用setDataSource()方法,会抛出IllegalStateException异常。

b. 好的编程习惯是不要疏忽了调用setDataSource()方法的时候可能会抛出的IllegalArgumentException异常和IOException异常。

 

3) 在开始播放之前,MediaPlayer对象必须要进入Prepared状态。

a. 有两种方法(同步和异步)可以使MediaPlayer对象进入Prepared状态:要么调用prepare()方法(同步),此方法返回就表示该MediaPlayer对象已经进入了Prepared状态;要么调用prepareAsync()方法(异步),此方法会使此MediaPlayer对象进入Preparing状态并返回,而内部的播放引擎会继续未完成的准备工作。当同步版本返回时或异步版本的准备工作完全完成时就会调用客户端程序员提供的OnPreparedListener.onPrepared()监听方法。可以调用MediaPlayer.setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener)方法来注册OnPreparedListener.

b. Preparing是一个中间状态,在此状态下调用任何具备边影响的方法的结果都是未知的!

c. 在不合适的状态下调用prepare()prepareAsync()方法会抛出IllegalStateException异常。当MediaPlayer对象处于Prepared状态的时候,可以调整音频/视频的属性,如音量,播放时是否一直亮屏,循环播放等。

 

4) 要开始播放,必须调用start()方法。当此方法成功返回时,MediaPlayer的对象处于Started状态。isPlaying()方法可以被调用来测试某个MediaPlayer对象是否在Started状  态。

a. 当处于Started状态时,内部播放引擎会调用客户端程序员提供的OnBufferingUpdateListener.onBufferingUpdate()回调方法,此回调方法允许应用程序追踪流播放的缓冲的状态。

b. 对一个已经处于Started 状态的MediaPlayer对象调用start()方法没有影响。

 

5) 播放可以被暂停,停止,以及调整当前播放位置。当调用pause()方法并返回时,会使MediaPlayer对象进入Paused状态。注意StartedPaused状态的相互转换在内部的播放引擎中是异步的。所以可能需要一点时间在isPlaying()方法中更新状态,若在播放流内容,这段时间可能会有几秒钟。   

a. 调用start()方法会让一个处于Paused状态的MediaPlayer对象从之前暂停的地方恢复播放。当调用start()方法返回的时候,MediaPlayer对象的状态会又变成Started状态。

b. 对一个已经处于Paused状态的MediaPlayer对象pause()方法没有影响。

 

6) 调用stop()方法会停止播放,并且还会让一个处于StartedPausedPreparedPlaybackCompleted状态的MediaPlayer进入Stopped状态。

对一个已经处于Stopped状态的MediaPlayer对象stop()方法没有影响。

 

7) 调用seekTo()方法可以调整播放的位置。

a. seekTo(int)方法是异步执行的,所以它可以马上返回,但是实际的定位播放操作可能需要一段时间才能完成,尤其是播放流形式的音频/视频。当实际的定位播放操作完成之后,内部的播放引擎会调用客户端程序员提供的OnSeekComplete.onSeekComplete()回调方法。可以通过setOnSeekCompleteListener(OnSeekCompleteListener)方法注册。

b. 注意,seekTo(int)方法也可以在其它状态下调用,比如PreparedPausedPlaybackCompleted状态。此外,目前的播放位置,实际可以调用getCurrentPosition()方法得到,它可以帮助如音乐播放器的应用程序不断更新播放进度

 

8) 当播放到流的末尾,播放就完成了。

a. 如果调用了setLooping(boolean)方法开启了循环模式,那么这个MediaPlayer对象会重新进入Started状态。

b. 若没有开启循环模式,那么内部的播放引擎会调用客户端程序员提供的OnCompletion.onCompletion()回调方法。可以通过调用MediaPlayer.setOnCompletionListener(OnCompletionListener)方法来设置。内部的播放引擎一旦调用了OnCompletion.onCompletion()回调方法,说明这个MediaPlayer对象进入了PlaybackCompleted状态。

c. 当处于PlaybackCompleted状态的时候,可以再调用start()方法来让这个MediaPlayer对象再进入Started状态。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值