本篇内容是我对几篇文章的总结,对MediaPlayer使用的整理。
mediaplayer高级使用
mediaplayer基本使用
Android下对于音频、视频的支持均需要使用到MediaPlayer,它主要用来控制Android下播放文件或流的类。
MediaPlayer是Android原生的多媒体播放器,可以用它来实现本地或者在线音视频的播放,同时它支持https和rtsp。
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时,调用reset()方法,MediaPlayer处于Idle状态。
调用release()方法,MediaPlayer处于End状态
Idle->End 就是MediaPlayer的完整的生命周期
注意:有些状态是可以双向转换的,有些只能单向环形转换。如果在某状态下,强行转换状态,会应发程序错误,例如在Preparing状态下切换到Started状态,是准备中强行开始播放,会出错。
MediaPlayer的相关方法及监听接口:
方法 | 介绍 | 状态 |
---|---|---|
setDataSource | 设置数据源 | Initialized |
prepare | 准备播放,同步 | Preparing —> Prepared |
prepareAsync | 准备播放,异步 | Preparing —> Prepared |
start | 开始或恢复播放 | Started |
pause | 暂停 | Paused |
stop | 停止 | Stopped |
seekTo | 到指定时间点位置 | PrePared/Started |
reset | 重置播放器 | Idle |
setAudioStreamType | 设置音频流类型 | – |
setDisplay | 设置播放视频的Surface | – |
setVolume | 设置声音 | – |
getBufferPercentage | 获取缓冲半分比 | – |
getCurrentPosition | 获取当前播放位置 | – |
getDuration | 获取播放文件总时间 | – |
setLooping(boolean looping) | 设置是否循环播放 | – |
isLooping() | 判断是否循环播放 | – |
isPlaying() | 判断是否正在播放 | – |
setWakeMode(Context context, int mode) | 设置CPU唤醒的状态 | – |
内部回调接口 | 介绍 | 状态 |
---|---|---|
OnPreparedListener | 准备监听 | Preparing ——>Prepared |
OnVideoSizeChangedListener | 视频尺寸变化监听 | – |
OnInfoListener | 指示信息和警告信息监听 | – |
OnCompletionListener | 播放完成监听 | PlaybackCompleted |
OnErrorListener | 播放错误监听 | Error |
OnBufferingUpdateListener | 缓冲更新监听 | – |
MediaPlayer在直接new出来之后进入Idle状态,
可以调用多个重载的setDataSource()方法从 Idle->Initialized状态
(如果调用setDataSource方法的时候,MediaPlayer对象不是Idle状态,会抛出异常,可以调用reset()方法回到Idle状态)调用prepared()和preparedAsyn()进入Prepared状态,prepared是同步方法,直接进入Prepared状态,preparedAsyn()是异步状态,先进入Preparing状态,通过OnPreparedListener.onPrepared()回调方法通知Prepared状态。
在Prepared状态下就可以调用start()方法进行播放了,此时进入started()状态,如果播放的是网络资源,Started状态下也会自动调用客户端注册的OnBufferingUpdateListener.OnBufferingUpdate()回调方法,对流播放缓冲的状态进行追踪。
- pause()方法和start()方法是对应的,调用pause()方法会进入Paused状态,调用start()方法重新进入Started状态,继续播放。
- stop()方法会使MdiaPlayer从Started、Paused、Prepared、PlaybackCompleted等状态进入到Stoped状态,播放停止。
- 当资源播放完毕时,如果调用了setLooping(boolean)方法,会自动进入Started状态重新播放,如果没有调用则会自动调用客户端播放器注册的OnCompletionListener.OnCompletion()方法,此时MediaPlayer进入PlaybackCompleted状态,在此状态里可以调用start()方法重新进入Started状态。
使用方式
- 创建MediaPlayer
- 设置数据源
- 设置音频流类型
- 调用准备 prepare
- 当处于就绪状态,调用start
1 | mediaPlayer = new MediaPlayer(); |
注意:一定要回收资源,MediaPlayer是很消耗系统资源的,所以在使用完MediaPlayer,不要等待系统自动回收,最好是主动回收资源。
1 | if (mediaPlayer != null && mediaPlayer.isPlaying()) { |
MediaPlayer的音频焦点
众所周知,Android是一个多任务的操作系统,所以对于音频的播放,也许有几个不同的媒体服务会同时播放,这样可能导致一个比较杂乱的声音环境,而错过一些重要的声音提醒。在Android2.2之后,Android提供了一种应用协商使用设备音频输出的机制,这种机制称为音频焦点。
当应用程序需要输出音频或通知的时候,需要请求音频焦点,当请求得到音频焦点之后,监听音频焦点的变换,当音频焦点变换了,根据返回回来的音频焦点码进行相应的处理。音频焦点的注册使用音频管理器的AudioManager.requestAudioFocus()方法设定。
AudioManager.OnAudioFocusChangeListener为音频焦点变换的监听器,其中需要实现一个方法:onAudioFocusChange(int focusChange)在音频焦点变换的时候回调。它有一个参数,为当前表示音频焦点对于当前应用的状态码,通过这个状态码指定对应的操作,有些时候音频状态改变了,并不一定需要停止音频的播放。
focusChange有一下几种状态码:
- AUDIOFOCUS_GAIN:获得音频焦点。
- AUDIOFOCUS_LOSS:失去音频焦点,并且会持续很长时间。这是我们需要停止MediaPlayer的播放。
- AUDIOFOCUS_LOSS_TRANSIENT:失去音频焦点,但并不会持续很长时间,需要暂停MediaPlayer的播放,等待重新获得音频焦点。
- AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:暂时失去音频焦点,但是无需停止播放,只需降低声音方法。
1 | audioManager = (AudioManager) getSystemService(this.AUDIO_SERVICE); |