天天看点

Android开发之Mediaplayer

 android提供了常见的音频、视频的编码、解码机制。借助于多媒体类mediaplayer的支持,开发人员可以很方便在在应用中播放音频、视频。本篇博客主要讲解在android平台下如何播放一个音频文件。

  本篇博客主要内容如下:

<a target="_blank" href="http://www.cnblogs.com/plokmju/p/android_mediaplayer.html#mediaplayer">mediaplayer</a>

<a target="_blank" href="http://www.cnblogs.com/plokmju/p/android_mediaplayer.html#audiosource">mediaplayer的音频源</a>

<a target="_blank" href="http://www.cnblogs.com/plokmju/p/android_mediaplayer.html#usermediaplayer">使用mediaplayer播放音乐</a>

<a target="_blank" href="http://www.cnblogs.com/plokmju/p/android_mediaplayer.html#userskill">mediaplayer使用技巧</a>

<a target="_blank" href="http://www.cnblogs.com/plokmju/p/android_mediaplayer.html#mp3demo">demo--一个简单的mp3播放器</a>

mediaplayer

  上面提到过,android下对于音频、视频的支持均需要使用到mediaplayer,它主要用来控制android下播放文件或流的类。mediaplayer处于android多媒体包下"android.media.mediaplayer",仅有一个无参的构造函数,虽然仅为我们提供了一个无参的构造函数,为了方便我们初始化,还为我们提供了几个静态的create()方法用于完成mediaplayer初始化的工作。

static mediaplayer create(context context,int resid):通过音频资源的id来创建一个mediaplayer实例。

static mediaplayer create(context context,uri uri):通过一个音频资源的uri地址来创建一个mediaplayer实例。

  mediaplayer除了通过上面两个create()方法在初始化的时候指定媒体资源,还可以通过mediaplayer.setdatasource()方法为初始化后的mediaplayer设置媒体资源,setdatasource()具有多个重载函数,适用于不同的媒体资源来源,以下讲解几个常用的,其他的可以查阅官方文档。

void setdatasource(string path):通过一个媒体资源的地址指定mediaplayer的数据源,这里的path可以是一个本地路径,也可以是网络路径。

void setdatasource(context context,uri uri):通过一个uri指定mediaplayer的数据源,这里的uri可以是网络路径或这一个内容提供者的uri。

void setdatasource(filedescriptor fd):通过一个filedescriptor指定一个mediaplayer的数据源。

  通过上面介绍的初始化mediaplayer的播放时媒体数据源的方法可以看出,mediaplayer支持的数据源有:本地文件、内部的uri(内容提供者)、外部uri。

  如,设置一个本地sd卡的资源:

  注意读内存卡,还需要设定访问内存卡的权限:

  如,设置一个外部uri的网络流媒体资源:

  如果访问网络流媒体资源,还需要设置访问网络的权限:

  mediaplayer其实是一个封装的很好的音频、视频流媒体操作类,如果查看其源码,会发现其内部是调用的native方法,所以它其实是有c++实现的。

  既然是一个流媒体操作类,那么必然涉及到,播放、暂停、停止等操作,实际上mediaplayer也为我们提供了相应的方法来直接操作流媒体。

void start():开始或恢复播放。

void stop():停止播放。

void pause():暂停播放。  

  通过上面三个方法,只要设定好流媒体数据源,即可在应用中播放流媒体资源,为了更好的操作流媒体,mediaplayer还为我们提供了一些其他的方法,这里列出一些常用的,详细内容参阅官方文档。

int getduration():获取流媒体的总播放时长,单位是毫秒。

int getcurrentposition():获取当前流媒体的播放的位置,单位是毫秒。

void seekto(int msec):设置当前mediaplayer的播放位置,单位是毫秒。

void setlooping(boolean looping):设置是否循环播放。

boolean islooping():判断是否循环播放。

boolean  isplaying():判断是否正在播放。

void prepare():同步的方式装载流媒体文件。

void prepareasync():异步的方式装载流媒体文件。

void release ():回收流媒体资源。 

void setaudiostreamtype(int streamtype):设置播放流媒体类型。

void setwakemode(context context, int mode):设置cpu唤醒的状态。

setnextmediaplayer(mediaplayer next):设置当前流媒体播放完毕,下一个播放的mediaplayer。

  大部分方法的看方法名就可以理解,但是有几个方法需要单独说明一下。

  在使用mediaplayer播放一段流媒体的时候,需要使用prepare()或prepareasync()方法把流媒体装载进mediaplayer,才可以调用start()方法播放流媒体。                 

  setaudiostreamtype()方法用于指定播放流媒体的类型,它传递的是一个int类型的数据,均以常量定义在audiomanager类中, 一般我们播放音频文件,设置为audiomanager.stream_music即可。

  

  除了上面介绍的一些方法外,mediaplayer还提供了一些事件的回调函数,这里介绍几个常用的:

setoncompletionlistener(mediaplayer.oncompletionlistener listener):当流媒体播放完毕的时候回调。

setonerrorlistener(mediaplayer.onerrorlistener listener):当播放中发生错误的时候回调。

setonpreparedlistener(mediaplayer.onpreparedlistener listener):当装载流媒体完毕的时候回调。

setonseekcompletelistener(mediaplayer.onseekcompletelistener listener):当使用seekto()设置播放位置的时候回调。

  在使用mediaplayer的使用过程中,有个小技巧需要说明一下:

  1、在使用start()播放流媒体之前,需要装载流媒体资源。这里最好使用prepareasync()用异步的方式装载流媒体资源。因为流媒体资源的装载是会消耗系统资源的,在一些硬件不理想的设备上,如果使用prepare()同步的方式装载资源,可能会造成ui界面的卡顿,这是非常影响用于体验的。因为推荐使用异步装载的方式,为了避免还没有装载完成就调用start()而报错的问题,需要绑定mediaplayer.setonpreparedlistener()事件,它将在异步装载完成之后回调。异步装载还有一个好处就是避免装载超时引发anr((application

not responding)错误。

Android开发之Mediaplayer
Android开发之Mediaplayer

  2、使用完mediaplayer需要回收资源。mediaplayer是很消耗系统资源的,所以在使用完mediaplayer,不要等待系统自动回收,最好是主动回收资源。

  3、使用mediaplayer最好使用一个service来使用,并且在service的ondestory()方法中回收mediaplayer资源,实际上,就算是直接使用activity承载mediaplayer,也最好在销毁的时候判断一下mediaplayer是否被回收,如果未被回收,回收其资源,因为底层调用的native方法,如果不销毁还是会在底层继续播放,而承载的组件已经被销毁了,这个时候就无法获取到这个mediaplayer进而控制它。

Android开发之Mediaplayer
Android开发之Mediaplayer

  4、对于单曲循环之类的操作,除了可以使用setlooping()方法进行设置之外,还可以为mediaplayer注册回调函数,mediaplayer.setoncompletionlistener(),它会在mediaplayer播放完毕被回调。

Android开发之Mediaplayer
Android开发之Mediaplayer

   5、因为mediaplayer一直操作的是一个流媒体,所以无可避免的可能一段流媒体资源,前半段可以正常播放,而中间一段因为解析或者源文件错误等问题,造成中间一段无法播放问题,需要我们处理这个错误,否则会影响ux(用户体验)。可以为mediaplayer注册回调函数setonerrorlistener()来设置出错之后的解决办法,一般重新播放或者播放下一个流媒体即可。  

Android开发之Mediaplayer
Android开发之Mediaplayer

  上面已经介绍了mediaplayer播放一段音频文件的所有需要用到的内容。下面通过一个简单的demo来演示如何使用mediaplayer播放一个sd卡上的mp3文件。操作mediaplayer应该放在service中完成,这里为了简单,使用activity直接操作mediaplayer。代码注释里写的很清楚里,这里不再累述。

  执行这个示例需要在/sdcard/目录下存在xm.mp3的文件。  

Android开发之Mediaplayer
Android开发之Mediaplayer

 效果展示:

Android开发之Mediaplayer
Android开发之Mediaplayer
Android开发之Mediaplayer

继续阅读