一.需要实现的接口
public MediaPlayer()
public void setDisplay(SurfaceHolder sh)
public void setDataSource(String path)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateException
public native void prepareAsync() throws IllegalStateException;
public void start() throws IllegalStateException
public interface OnPreparedListener
public void setOnPreparedListener(OnPreparedListener listener)
public interface OnErrorListener
public void setOnErrorListener(OnErrorListener listener)
public interface OnCompletionListener
public void setOnCompletionListener(OnCompletionListener listener)
二.具有的方法
方法 | 说明 |
MediaPlayer | 构造方法 |
create | 创建一个要播放的多媒体 |
getCurrentPosition | 得到当前播放位置 |
getDuration | 得到文件的时间 |
getVideoHeight | 得到视频的高度 |
getVideoWidth | 得到视频的宽度 |
isLooping | 是否循环播放 |
isPlaying | 是否正在播放 |
pause | 暂停 |
prepare | 准备(同步) |
prepareAsync | 准备(异步) |
release | 释放MediaPlayer对象相关的资源 |
reset | 重置MediaPlayer对象为刚刚创建的状态 |
seekTo | 指定播放的位置(以毫秒为单位的时间) |
setAudioStreamType | 设置流媒体的类型 |
setDataSource | 设置多媒体数据来源(位置) |
setDisplay | 设置用SurfaceHolder来显示多媒体 |
setLooping | 设置是否循环播放 |
setOnButteringUpdateListener | 网络流媒体的缓冲监听 |
setOnErrorListener | 设置错误信息监听 |
setOnVideoSizeChangedListener | 视频尺寸监听 |
setScreenOnWhilePlaying | 设置是否使用SurfaceHolder来保持屏幕显示 |
setVolume | 设置音量 |
start | 开始播放 |
stop | 停止播放 |
三.工作流程:
1,首先创建MediaPlayer对象; *
a 直接new出来
- MediaPlayer mp = new MediaPlayer();
b 使用create方式
使用create方法创建成功后,mediaPlayer处于Prepared状态。可以直接start播放。
1 2 | mediaPlayer = MediaPlayer.create(getApplicationContext(), Uri.fromFile(file)); mediaPlayer.start(); |
当然上面首先得在res文件夹下新建raw文件夹,并放置一个test文件
2,然后调用setDataSource()方法来设置音频文件的路径;**
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");
播放网络音频时,如果使用的是http,有可能会报错
1 | java.io.IOException: Cleartext HTTP traffic to demo.com not permitted |
可以简单地设置一下manifest,设置usesCleartextTraffic=”true”
1 2 | <application android:usesCleartextTraffic= "true" > |
d. assets里的资源
例如设置使用assets里的资源。实际情况可能需要try catch。
1 2 3 4 | AssetFileDescriptor fd = null ; MediaPlayer mediaPlayer = new MediaPlayer(); fd = context.getApplicationContext().getAssets().openFd(name); mediaPlayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength()); |
e. 本地文件,需要文件的绝对路径。
| mediaPlayer.setDataSource(file.getAbsolutePath()); |
f. 获取文件的Uri来创建mediaPlayer。
1 | mediaPlayer = MediaPlayer.create(getApplicationContext(), Uri.fromFile(file)); |
3,再调用prepare()方法使MediaPlayer进入到准备状态;
同步和异步准备音频资源。prepareAsync()
是异步的方式,prepare是同步的。注意线程调度问题,同时不要阻塞UI线程。
使用异步方式准备音频,经常与MediaPlayer.OnPreparedListener
监听器配合使用。异步准备时,也可以进行其他的设置。
1 2 3 4 5 6 7 | mediaPlayer.prepareAsync(); mediaPlayer.setOnPreparedListener( new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mediaPlayer) { mediaPlayer.start(); // 准备好了就播放 } }); |
4,调用start方法就可以播放音频。
5. 其他功能
循环播放 - Looping
设置循环播放setLooping。
mediaPlayer.setLooping(true);
播放完毕后,不会回调OnCompletionListener,而是从头播放当前音频。
播放 - start
播放音频,调用start方法。
mediaPlayer.start();
处于Prepared,Pause和PlaybackComplete状态时,可以调用start方法,进入Started状态。
暂停 - pause
暂停播放,使用pause方法。在暂停前先判断一下mediaPlayer的是否在播放。
1 2 3 | if (mediaPlayer.isPlaying()) { mediaPlayer.pause(); } |
暂停成功则处于Paused状态。
停止 - stop
回顾一下MediaPlayer状态切换的图示,我们可以得知在播放中,暂停,播放完成这3个状态下,可以调用stop方法,进入Stopped状态。
mediaPlayer.stop();
调进度 - seekTo
调整播放进度。我们平时使用音乐播放软件一般都会有这个功能。
seekTo方法接受一个毫秒参数。
1 2 | int targetMS = ( int ) (percent * mediaPlayer.getDuration()); mediaPlayer.seekTo(targetMS); |
seekTo并不会改变MediaPlayer的状态。
1 2 | int targetMS = ( int ) (percent * mediaPlayer.getDuration()); mediaPlayer.seekTo(targetMS); |
reset后的mediaPlayer进入Idle状态。需要重新设置音源与准备。
释放 - release
不再使用这个mediaPlayer时,应当尽快释放掉,以释放相关的资源。
调用release后,mediaPlayer进入End状态。此时这个mediaPlayer就不能再使用了。
常用监听器
缓冲监听器 OnBufferingUpdateListener
比如我们加载网络音频的时候,常用这个监听器来监听缓冲进度。显示缓冲进度,也可以提高用户体验。
1 2 3 4 5 6 7 | mMediaPlayer.prepareAsync(); mMediaPlayer.setOnBufferingUpdateListener( new MediaPlayer.OnBufferingUpdateListener() { @Override public void onBufferingUpdate(MediaPlayer mp, int percent) { // percent代表缓冲百分比 } }); |
错误监听器 OnErrorListener
1 2 3 4 5 6 | mediaPlayer.setOnErrorListener( new MediaPlayer.OnErrorListener() { @Override public boolean onError(MediaPlayer mediaPlayer, int i, int i1) { return true ; // 返回true表示在此处理错误,不会回调onCompletion } }); |
注意onError的返回值。可以选择自己处理error。
1 2 3 4 5 | * @return True if the method handled the error, false if it didn't. * Returning false , or not having an OnErrorListener at all, will * cause the OnCompletionListener to be called. */ boolean onError(MediaPlayer mp, int what, int extra); |
播放完毕监听器 OnCompletionListener
1 2 3 4 5 6 | mediaPlayer.setOnCompletionListener( new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mediaPlayer) { // 播放完毕 } }); |
使用示例
播放assets里的音频
播放assets里的音频文件,使用到AssetFileDescriptor类。使用后记得关闭AssetFileDescriptor。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | private void playAssetsAudio( final String name, Context context) { Log.d(TAG, "playAssetWordSound: try to play assets sound file. -> " + name); AssetFileDescriptor fd = null ; try { MediaPlayer mediaPlayer; Log.v(TAG, "Looking in assets." ); fd = context.getApplicationContext().getAssets().openFd(name); mediaPlayer = new MediaPlayer(); mediaPlayer.reset(); mediaPlayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength()); mediaPlayer.prepareAsync(); mediaPlayer.setOnPreparedListener( new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mediaPlayer) { Log.d(TAG, "onPrepared: " + name); mediaPlayer.start(); } }); mediaPlayer.setOnCompletionListener( new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { mp.release(); Log.d(TAG, "onCompletion: " + name); } }); mediaPlayer.setOnErrorListener( new MediaPlayer.OnErrorListener() { @Override public boolean onError(MediaPlayer mp, int i, int i1) { mp.release(); return true ; } }); } catch (Exception e) { try { if (fd != null ) { fd.close(); } } catch (Exception e1) { Log.e(TAG, "Exception close fd: " , e1); } } finally { if (fd != null ) { try { fd.close(); } catch (IOException e) { Log.e(TAG, "Finally, close fd " , e); } } } } |
播放本地音频文件
尝试播放音频文件。仅播放一次。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | private void playAudioFile( final File file) { Log.d(TAG, "playAudioFile: " + file.getAbsolutePath()); MediaPlayer mediaPlayer; try { mediaPlayer = new MediaPlayer(); mediaPlayer.setLooping( false ); mediaPlayer.setDataSource(file.getAbsolutePath()); mediaPlayer.prepare(); mediaPlayer.start(); mediaPlayer.setOnCompletionListener( new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { mp.release(); } }); mediaPlayer.setOnErrorListener( new MediaPlayer.OnErrorListener() { @Override public boolean onError(MediaPlayer mediaPlayer, int i, int i1) { Log.d(TAG, "Play local sound onError: " + i + ", " + i1); return true ; } }); } catch (Exception e) { Log.e(TAG, "playAudioFile: " , e); } } |
播放在线音频
设置url,播放在线音频
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | private void playOnlineSound(String soundUrlDict) { try { MediaPlayer mediaPlayer = new MediaPlayer(); mediaPlayer.setDataSource(soundUrlDict); mediaPlayer.prepareAsync(); mediaPlayer.setOnPreparedListener( new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mediaPlayer) { mediaPlayer.start(); } }); mediaPlayer.setOnCompletionListener( new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { if (mp != null ) { mp.release(); } Log.d(TAG, "onCompletion: play sound." ); } }); mediaPlayer.setOnErrorListener( new MediaPlayer.OnErrorListener() { @Override public boolean onError(MediaPlayer mediaPlayer, int i, int i1) { Log.d(TAG, "Play online sound onError: " + i + ", " + i1); return false ; } }); } catch (IOException e1) { Log.e(TAG, "url: " , e1); } } |