Android播放器MediaPlayer(上)

扯点废话

作为一名在学安卓的菜鸟,看完第一行代码,总想做点什么项目,思来想去,还是做音乐播放器吧,还算感点兴趣,其它的什么新闻之类的,好像根本提不起兴趣~~于是就按郭神的第一行代码上用到的,决定用Android提供的MediaPlayer,文章的记录流程就按api文档上的走。

正题开始

状态图

下图显示了MediaPlayer对象的生命周期和状态。
Android播放器MediaPlayer(上)从这个状态图可以看出MediaPlayer对象有以下状态:

1. 当使用new或调用reset()刚创建MediaPlayer对象时,它处于空闲状态;调用release()后,它处于结束状态。这两种状态之间是MediaPlayer对象的生命周期。

  • 在调用reset()后,新构造的MediaPlayer对象和MediaPlayer对象之间有一个细微但重要的区别:两种情况下,调用比如getCurrentPosition(), getDuration(), getVideoHeight(), getVideoWidth(), setAudioStreamType(int), setLooping(boolean), setVolume(float, float), pause(), start(), stop(), seekTo(int), prepare() or prepareAsync()等方法都是程序错误的。
  • 如果在构造MediaPlayer对象之后立即调用这些方法中的任何一个,则用户提供的回调方法OnErrorListener.onError()将不会被内部播放器引擎调用,且对象状态保持不变;但是如果在reset()之后立即调用这些方法,那么用户提供的回调方法OnErrorListener.onError()将被内部播放器引擎调用,对象将被转移到错误状态。
  • 还建议一旦不再使用MediaPlayer对象,立即调用release(),以便可以立即释放与MediaPlayer对象关联的内部播放器引擎使用的资源。资源可能包括单例资源,如硬件加速组件和调用release()失败可能导致MediaPlayer对象的后续实例退回到软件实现或完全失败。一旦MediaPlayer对象处于结束状态,就不能再使用它,也没有办法将其恢复到任何其他状态。
  • 此外,使用new创建的MediaPlayer对象处于空闲状态,而使用重载的方法create()创建的对象则不处于空闲状态。实际上,如果使用create的方法创建成功,则对象处于准备状态。

2. 一般情况下,一些回放控制操作可能会由于各种原因而失败,比如不支持音频/视频格式、音频/视频交织不好、分辨率过高、流超时等。因此,在这种情况下,错误报告和恢复是一个重要的问题。有时,由于编程错误,在无效状态下调用回放控制操作也可能发生。在所有这些错误条件下,如果一个OnErrorListener已经通过setOnErrorListener(android.media.MediaPlayer.OnErrorListener)预先注册,那么内部播放器引擎将调用用户提供的OnErrorListener. onerror()方法。

  • 重要的是要注意,一旦发生错误,MediaPlayer对象将进入错误状态(除了上面提到的),即便应用程序没有注册错误侦听器。
  • 为了重用处于错误状态的MediaPlayer对象并从错误中恢复,可以调用reset()将该对象恢复到其空闲状态。
  • 让应用程序注册一个OnErrorListener来查找来自内部播放器引擎的错误通知,这是一个很好的编程习惯。
  • 抛出IllegalStateException是为了防止编程错误,如调用prepare()、prepareAsync()或以无效状态重载的setDataSource方法之一。

3. 调用setDataSource()的重载方法会将处于空闲状态的MediaPlayer对象传输到初始化状态。

  • 如果在任何其他状态中调用setDataSource(),就会抛出IllegalStateException
  • 好的编程习惯是始终注意从重载的setDataSource方法中可能抛出的IllegalArgumentExceptionIOException

4. 在开始播放之前,MediaPlayer对象必须首先进入准备状态。

  • 有两种方式(同步和异步)可以达到准备状态:一种是调用同步的prepare()方法,在调用返回后,会将对象转换到准备状态;另一种是调用异步的prepareAsync()方法,在调用返回后,它首先将对象转移到准备状态(这几乎是以正确的方式发生的),而内部的播放器引擎继续处理其余的准备工作,直到准备工作完成。当准备工作完成或当prepare()调用返回时,如果一个OnPreparedListener事先通过setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener .OnPreparedListener)注册了,那么内部的播放器引擎就会调用用户提供的一个回调方法OnPreparedListener接口的onPrepared()
  • 需要注意的是,准备状态是一个瞬间状态,并且在MediaPlayer对象处于准备状态时调用任何具有副作用的方法的行为都是未定义的。
  • 如果在任何其他状态中调用了prepare()prepareAsync(),则抛出IllegalStateException
  • 在准备状态下,可以通过调用相应的set方法来调整audio/sound volume、screenonwhile play、loop等属性。

5. 要开始播放,必须调用start()。在start()成功返回后,MediaPlayer对象处于启动状态。可以调用isPlaying()来测试MediaPlayer对象是否处于启动状态。

  • 当处于启动状态时,如果一个OnBufferingUpdateListener已经预先通过setOnBufferingUpdateListener(OnBufferingUpdateListener)注册了,那么内部的播放器引擎将调用一个用户提供的OnBufferingUpdateListener. onbufferingupdate()回调方法。这个回调允许应用程序在播放音频/视频时跟踪缓冲状态。
  • 调用start()不会影响已经处于启动状态的MediaPlayer对象。

6. 可暂停和停止播放,并可调整当前播放位置。播放可以通过pause()暂停。当pause()调用返回时,MediaPlayer对象进入暂停状态。请注意,从启动状态到暂停状态的转换(反之亦然)是在播放器引擎中异步进行的。在调用isPlaying()中更新状态可能需要一些时间,对于流内容可能需要几秒钟。

  • 调用start()来恢复暂停的MediaPlayer对象的播放,恢复的播放位置与暂停的位置相同。当调用start()返回时,暂停的MediaPlayer对象将返回到开始状态。
  • 调用pause()对已经处于暂停状态的MediaPlayer对象没有影响。

7. 调用stop()将停止播放,并使处于启动、暂停、准备或播放完成状态的MediaPlayer对象进入停止状态。

  • 一旦进入停止状态,就不能开始回放,直到调用prepare()prepareAsync()将MediaPlayer对象再次设置为准备状态。
  • 调用stop()对已经处于停止状态的MediaPlayer对象没有影响。

8. 回放位置可以通过调用seekTo(int)进行调整。

  • 虽然异步的seekTo(int)调用以正确的方式返回,但实际的seek操作可能需要一段时间才能完成,特别是对于正在流化的音频/视频。当实际的seek操作完成时,如果已经通过setOnSeekCompleteListener(OnSeekCompleteListener)注册了OnSeekCompleteListener,那么内部的播放器引擎将调用一个用户提供的OnSeekComplete.onSeekComplete()
  • 请注意,seekTo(int)也可以在其他状态下调用,比如准备状态、和播放完成状态。
  • 此外,可以通过调用getCurrentPosition()来检索实际的当前播放位置,这对于需要跟踪播放进度的音乐播放器等应用程序很有帮助。

9. 当播放到达流的末端时,播放就完成了。

  • 如果使用setLooping(true)设置了循环播放模式模式,那么MediaPlayer对象将保持在开始状态。
  • 如果循环模式设置为false,则播放器引擎调用用户提供的回调方法OnCompletion.onCompletion(),如果一个OnCompletionListener是预先通过setOnCompletionListener(OnCompletionListener)注册的。回调的调用表明对象现在处于播放完成状态。
  • 在播放完成状态下,调用start()可以从音频/视频源的开头重新开始播放。

一些使用MediaPlayer时常用到的接口

  • MediaPlayer.OnBufferingUpdateListener:指示在网络上传输的媒体资源的缓冲状态。
  • MediaPlayer.OnCompletionListener:播放完成时回调
  • MediaPlayer.OnErrorListener:异步操作中出现错误时回调(其他错误将在方法调用时抛出异常)
  • MediaPlayer.OnPreparedListener:当媒体源准备好要播放时回调。
  • MediaPlayer.OnSeekCompleteListener:seek操作完成时回调。

怎样查看API文档

因为基本上是翻译的API文档,所以我觉得这里有必要说一下怎么样看API文档,新手可以看一看,这里以查看MediaPlayer这个类为例,步骤如下:

1. 下载API文档

打开Android studio,按箭头一步步点击。

Android播放器MediaPlayer(上)
Android播放器MediaPlayer(上)
Android播放器MediaPlayer(上)2. 找到文档位置

第一步找到sdk的文件位置:
Android播放器MediaPlayer(上)第二步,打开
Android播放器MediaPlayer(上)Android播放器MediaPlayer(上)

结语

为什么突然结束了?因为我不耐烦了,这样一步步截图真的挺烦的,如果有不会的就留下评论吧。下一篇写MediaPlayer的使用。