`
Jacular
  • 浏览: 182271 次
  • 性别: Icon_minigender_1
  • 来自: 云南
社区版块
存档分类
最新评论

Android MediaPlayer状态机

 
阅读更多

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

通过这张图,我们可以知道一个MediaPlayer 对象有以下的状态:

1)当一个MediaPlayer对象被刚刚用new操作符创建或是调用了reset()方法后,它就处于Idle状态。当调用了release()方法后,它就处于End状态。这两种状态之间是MediaPlayer对象的生命周期。
1.1) 在一个新构建的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() 方法了,并将错误的状态传入。
1.2) 我们建议,一旦一个MediaPlayer 对象不再被使用,应立即调用release() 方法来释放在内部的播放引擎中与这个MediaPlayer 对象关联的资源。资源可能包括如硬件加速组件的单态组件,若没有调用release() 方法可能会导致之后的MediaPlayer 对象实例无法使用这种单态硬件资源,从而退回到软件实现或运行失败。一旦MediaPlayer 对象进入了End状态,它不能再被使用,也没有办法再迁移到其它状态。
1.3) 此外,使用new 操作符创建的MediaPlayer 对象处于Idle状态,而那些通过重载的create() 便利方法创建的MediaPlayer 对象却不是处于Idle状态。事实上,如果成功调用了重载的create() 方法,那么这些对象已经是Prepare状态了。 

2) 在 一般情况下,由于种种原因一些播放控制操作可能会失败,如不支持的音频/视频格式,缺少隔行扫描的音频/视频,分辨率太高,流超时等原因,等等。因此,错 误报告和恢复在这种情况下是非常重要的。有时,由于编程错误,在处于无效状态的情况下调用了一个播放控制操作可能发生。在所有这些错误条件下,内部的播放 引擎会调用一个由客户端程序员提供的OnErrorListener.onError()方法。客户端程序员可以通过调用 MediaPlayer.setOnErrorListener(android.media.MediaPlayer.OnErrorListener) 方法来注册OnErrorListener.
2.1) 一旦发生错误,MediaPlayer 对象会进入到Error状态。
2.2) 为了重用一个处于Error状态的MediaPlayer 对象,可以调用reset() 方法来把这个对象恢复成Idle状态。
2.3) 注册一个OnErrorListener 来获知内部播放引擎发生的错误是好的编程习惯。
2.4) 在不合法的状态下调用一些方法,如prepare(),prepareAsync()setDataSource() 方法会抛出IllegalStateException 异常。 

3) 调 用setDataSource(FileDescriptor)方法,或setDataSource(String)方法,或 setDataSource(Context,Uri)方法,或setDataSource(FileDescriptor,long,long)方法会 使处于Idle状态的对象迁移到Initialized状态。
3.1) 若当此MediaPlayer 处于其它的状态下,调用setDataSource() 方法,会抛出IllegalStateException 异常。
3.2) 好的编程习惯是不要疏忽了调用setDataSource() 方法的时候可能会抛出的IllegalArgumentException 异常和IOException 异常。 

4) 在开始播放之前,MediaPlayer对象必须要进入Prepared状态。
4.1) 有两种方法(同步和异步)可以使MediaPlayer 对象进入Prepared状态:要么调用prepare() 方法(同步 ),此方法返回就表示该MediaPlayer 对象已经进入了Prepared状态;要么调用prepareAsync() 方法(异步 ),此方法会使此MediaPlayer 对象进入Preparing状态并返回,而内部的播放引擎会继续未完成的准备工作。当同步版本返回时或异步版本的准备工作完全完成时就会调用客户端程序员提供的OnPreparedListener.onPrepared() 监听方法。可以调用MediaPlayer.setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener) 方法来注册OnPreparedListener .
4.2) Preparing是一个中间状态,在此状态下调用任何具备边影响的方法的结果都是未知的!
4.3) 在不合适的状态下调用prepare()prepareAsync() 方法会抛出IllegalStateException 异常。当MediaPlayer 对象处于Prepared 状态的时候,可以调整音频/视频的属性,如音量,播放时是否一直亮屏,循环播放等。 

5) 要开始播放,必须调用start()方法。当此方法成功返回时,MediaPlayer的对象处于Started状态。isPlaying()方法可以被调用来测试某个MediaPlayer对象是否在Started状态。
5.1) 当处于Started状态时,内部播放引擎会调用客户端程序员提供的OnBufferingUpdateListener.onBufferingUpdate() 回调方法,此回调方法允许应用程序追踪流播放的缓冲的状态。
5.2) 对一个已经处于Started 状态的MediaPlayer 对象调用start() 方法没有影响。

6) 播放可以被暂停,停止,以及调整当前播放位置。当调用pause()方法并返回时,会使MediaPlayer对象进入Paused状态。注意 Started与Paused状态的相互转换在内部的播放引擎中是异步的。所以可能需要一点时间在isPlaying()方法中更新状态,若在播放流内 容,这段时间可能会有几秒钟。
6.1) 调用start() 方法会让一个处于Paused状态的MediaPlayer 对象从之前暂停的地方恢复播放。当调用start() 方法返回的时候,MediaPlayer 对象的状态会又变成Started状态。
6.2) 对一个已经处于Paused状态的MediaPlayer 对象pause() 方法没有影响。

7) 调用stop()方法会停止播放,并且还会让一个处于Started,Paused,Prepared或PlaybackCompleted状态的MediaPlayer进入Stopped状态。
7.1) 对一个已经处于Stopped状态的MediaPlayer 对象stop() 方法没有影响。

8) 调用seekTo()方法可以调整播放的位置。
8.1) seekTo(int) 方法是异步执行的,所以它可以马上返回,但是实际的定位播放操作可能需要一段时间才能完成,尤其是播放流形式的音频/视频。当实际的定位播放操作完成之后,内部的播放引擎会调用客户端程序员提供的OnSeekComplete.onSeekComplete() 回调方法。可以通过setOnSeekCompleteListener(OnSeekCompleteListener) 方法注册。
8.2) 注意,seekTo(int) 方法也可以在其它状态下调用,比如Prepared,Paused和PlaybackCompleted状态。此外,目前的播放位置,实际可以调用getCurrentPosition() 方法得到,它可以帮助如音乐播放器的应用程序不断更新播放进度

9) 当播放到流的末尾,播放就完成了。
9.1) 如果调用了setLooping(boolean) 方法开启了循环模式,那么这个MediaPlayer 对象会重新进入Started状态。
9.2) 若没有开启循环模式,那么内部的播放引擎会调用客户端程序员提供的OnCompletion.onCompletion() 回调方法。可以通过调用MediaPlayer.setOnCompletionListener(OnCompletionListener) 方法来设置。内部的播放引擎一旦调用了OnCompletion.onCompletion() 回调方法,说明这个MediaPlayer 对象进入了PlaybackCompleted状态。
9.3) 当处于PlaybackCompleted状态的时候,可以再调用start() 方法来让这个MediaPlayer 对象再进入Started状态。

分享到:
评论

相关推荐

    Android 媒体开发之MediaPlayer状态机接口方法实例解析

    MediaPlayer 状态机 介绍 Android MediaPlayer 状态即图例 : 1. Idle (闲置) 状态 和 End (结束) 状态 MediaPlayer 对象声明周期 : 从 Idle 到 End 状态就是 MediaPlayer 整个生命周期; — 生命周期开始 : 进入 ...

    android MediaPlayer播放视频网络URL,asset目录下文件,本地视频文件

    - `MediaPlayer`状态管理:了解其状态机(初始化、准备中、已准备、播放中、暂停、结束等)非常重要,以避免状态不匹配导致的问题。 - 错误处理:务必捕获异常并妥善处理,避免应用崩溃。 - 视频渲染:若需要在界面...

    Android MediaPlayer研究问题

    1. Android MediaPlayer的基本用法和状态机模型。 2. MediaPlayer在实际使用中可能遇到的问题,如状态转换错误、内存泄漏等。 3. 深入分析MediaPlayer的源码,以理解其内部工作原理。 4. 使用工具如Logcat进行调试的...

    mediaplayer_Android

    3. 状态管理:理解`MediaPlayer`的状态机非常重要,避免在错误状态下调用方法,否则可能导致不可预测的行为。 4. 权限:如果播放网络资源,需要在AndroidManifest.xml中添加`<uses-permission android:name="android...

    android下mediaplayer播放器

    在Android平台上,`MediaPlayer`是系统提供的一个核心组件,用于处理多媒体内容的播放,包括音频和视频。这个组件非常适合开发简单到中等复杂的媒体播放应用,对于初学者来说,理解和掌握`MediaPlayer`的使用是非常...

    安卓Android源码——(MediaPlayer音乐).zip

    MediaPlayer遵循一个状态机模型,其状态包括初始状态、准备就绪、播放、暂停等,开发者需要理解这些状态以便正确操作。 二、初始化与设置 使用MediaPlayer通常始于创建一个实例,然后加载媒体资源。例如,你可以...

    MediaPlayer

    4. 事件监听:通过实现`OnCompletionListener`、`OnErrorListener`、`OnPreparedListener`等接口,可以监听MediaPlayer的状态变化,如播放结束、错误发生或准备就绪。 5. 缓冲和预加载:对于网络流媒体,可以使用`...

    Android MediaPlayer 音乐播放器扫描 本地音乐、上一曲、下一曲切歌、播放本地音乐

    Android MediaPlayer 本地音乐播放器 运行截图 为了不浪费您的时间,先看一下运行的效果图, 一进去先进行音乐扫描,然后列表展示出来,点击即可播放。 演示视频地址 源码地址 GitHub 项目地址 这个给不想浪费时间...

    [Android]MediaPlayer类[定义].pdf

    总结来说,理解和掌握MediaPlayer类的状态机模型,以及正确的错误处理和资源管理策略,对于在Android应用中实现可靠和高效的多媒体播放功能至关重要。开发者需要谨慎处理不同状态下的操作,并确保在必要时进行错误...

    android调频收音机源码

    在Android平台上开发调频收音机应用是一项技术性较强的工作,涉及到音频处理、硬件接口通信以及用户界面设计等多个方面。本源码提供了实现这一功能的基础框架,帮助开发者深入理解其工作原理并进行定制化开发。以下...

    Android Media-使用MediaPlayer播放SD卡中的音频

    `MediaPlayer`对象是一个状态机,它有多个状态,如初始化、准备、播放、暂停等,开发者需要正确管理这些状态以确保播放的顺利进行。创建`MediaPlayer`实例后,通常先调用`setDataSource()`方法指定音频文件的路径,...

    用Android的 Media Codec播放RTSP视频流.rar

    在实现过程中,要注意处理各种异常和状态变化,例如解码错误、网络中断等。还要确保在合适的时机释放所有资源,防止内存泄漏。此外,考虑到不同设备可能支持不同的编解码器,应做好兼容性测试,确保在多种设备上都能...

    Android项目源码Nature音乐播放器

    - **MediaPlayer API**:Nature音乐播放器使用了Android自带的MediaPlayer类来播放音频文件。这个API支持多种音频格式,如MP3、AAC等,并提供了播放、暂停、停止、快进、后退等基本控制。 - **AudioFocus**:为了...

    基于Android的飞机大战游戏

    9. **音频处理**:背景音乐和音效的播放是提升游戏体验的重要部分,Android提供了MediaPlayer和SoundPool类来处理音频资源。 10. **数据存储**:游戏状态、分数等信息可能需要持久化存储,Android提供了...

    MediaPlayer(Flagment)

    3. **状态机**:`MediaPlayer`遵循一个复杂的状态机模型,包括IDLE、INITIALIZED、PREPARING、PREPARED、STARTED、PAUSED、STOPPED、PLAYBACK_COMPLETED、END等状态。理解每个状态的含义和转换规则能避免许多错误。 ...

    android飞机大战源码,直接运行即可

    这些都需要在游戏循环中实现,可能涉及到计时器和状态机的设计。 4. **资源管理**:包括图像、音频和动画的加载和释放。Android提供了Bitmap类用于加载图片,MediaPlayer或SoundPool用于播放音频。 5. **触摸事件...

    Android游戏大战飞机源码

    7. **状态管理**:游戏可能有多个状态,如开始、暂停、游戏结束等,需要一个状态机来管理这些状态的转换。 8. **数据持久化**:如果游戏包含得分或其他需要保存的数据,可以使用SharedPreferences或SQLite数据库来...

    android游戏开发例子_飞机大战怪兽

    例如,使用Activity的生命周期方法或自定义游戏状态机。 8. **音频处理**:背景音乐和音效也是游戏的一部分,Android提供MediaPlayer和SoundPool等类来播放音频。 9. **分享功能**:描述中提到的“结果分享”,...

Global site tag (gtag.js) - Google Analytics