Android MediaPlayer类详解

Android的多媒体框架支持各种常见的多媒体类型,这样在程序中可以很容易地集成音频、视频或者图片。Android下对于音频或者视频的支持均需要使用到MediaPlayer

MediaPlayer处于Android多媒体包下"android.media.MediaPlayer",仅有一个无参的构造函数,虽然Android平台仅为我们提供了一个无参的构造函数,但是为了方便我们初始化,还为我们提供了几个静态的create()方法用于完成MediaPlayer初始化的工作。(常用的两个)

  • static MediaPlayer create(Context context,int resid):通过给定的Id来创建一个MediaPlayer实例。
  • static MediaPlayer create(Context context,Uri uri):通过给定的Uri来创建一个MediaPlayer实例。
    还有一些重载的create方法,请自行查看API

MediaPlayer具体方法介绍:

  • void setDataSource(String path) 通过一个具体的路径来设置MediaPlayer的数据源,path可以是本地的一个路径,也可以是一个网络路径
  • void setDataSource(Context context, Uri uri) 通过给定的Uri来设置MediaPlayer的数据源,这里的Uri可以是网络路径或是一个ContentProvider的Uri。
  • void setDataSource(MediaDataSource dataSource) 通过提供的MediaDataSource来设置数据源
  • void setDataSource(FileDescriptor fd) 通过文件描述符FileDescriptor来设置数据源
  • int getCurrentPosition() 获取当前播放的位置
  • int getAudioSessionId() 返回音频的session ID
  • int getDuration() 得到文件的时间
  • TrackInfo[] getTrackInfo() 返回一个track信息的数组
  • boolean isLooping () 是否循环播放
  • boolean isPlaying() 是否正在播放
  • void pause () 暂停
  • void start () 开始
  • void stop () 停止
  • void prepare() 同步的方式装载流媒体文件。
  • void prepareAsync() 异步的方式装载流媒体文件。
  • void reset() 重置MediaPlayer至未初始化状态。
  • void release () 回收流媒体资源。
  • void seekTo(int msec) 指定播放的位置(以毫秒为单位的时间)
  • void setAudioStreamType(int streamtype) 指定流媒体类型
  • void setLooping(boolean looping) 设置是否单曲循环
  • void setNextMediaPlayer(MediaPlayer next) 当 当前这个MediaPlayer播放完毕后,MediaPlayer next开始播放
  • void setWakeMode(Context context, int mode):设置CPU唤醒的状态。
  • **setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener listener) 网络流媒体的缓冲变化时回调 **
  • setOnCompletionListener(MediaPlayer.OnCompletionListener listener) 网络流媒体播放结束时回调
  • **setOnErrorListener(MediaPlayer.OnErrorListener listener) 发生错误时回调 **
  • setOnPreparedListener(MediaPlayer.OnPreparedListener listener):当装载流媒体完毕的时候回调。

在使用MediaPlayer播放一段流媒体的时候,需要使用prepare()或prepareAsync()方法把流媒体装载进MediaPlayer,才可以调用start()方法播放流媒体。
 setAudioStreamType()方法用于指定播放流媒体的类型,它传递的是一个int类型的数据,均以常量定义在AudioManager类中, 一般我们播放音频文件,设置为AudioManager.STREAM_MUSIC即可。

MediaPlayer使用注意事项

  1. 在使用start()播放流媒体之前,需要装载流媒体资源。这里最好使用prepareAsync()用异步的方式装载流媒体资源。因为流媒体资源的装载是会消耗系统资源的,在一些硬件不理想的设备上,如果使用prepare()同步的方式装载资源,可能会造成UI界面的卡顿,这是非常影响用于体验的。因为推荐使用异步装载的方式,为了避免还没有装载完成就调用start()而报错的问题,需要绑定MediaPlayer.setOnPreparedListener()事件,它将在异步装载完成之后回调。异步装载还有一个好处就是避免装载超时引发ANR((Application Not Responding)错误。
                mediaPlayer = new MediaPlayer();
                mediaPlayer.setDataSource(path);
                mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                
                // 通过异步的方式装载媒体资源
                mediaPlayer.prepareAsync();
                mediaPlayer.setOnPreparedListener(new OnPreparedListener() {                    
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        // 装载完毕回调
                        mediaPlayer.start();
                    }
                });
  1. 使用完MediaPlayer需要回收资源。MediaPlayer是很消耗系统资源的,所以在使用完MediaPlayer,不要等待系统自动回收,最好是主动回收资源。
  if (mediaPlayer != null && mediaPlayer.isPlaying()) {
            mediaPlayer.stop();
            mediaPlayer.release();
            mediaPlayer = null;
        }
  1. 对于单曲循环之类的操作,除了可以使用setLooping()方法进行设置之外,还可以为MediaPlayer注册回调函数,MediaPlayer.setOnCompletionListener(),它会在MediaPlayer播放完毕被回调。
// 设置循环播放
//                mediaPlayer.setLooping(true);
                mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
                    @Override
                    public void onCompletion(MediaPlayer mp) {
                        // 在播放完毕被回调
                        play();                        
                    }
                });
  1. 因为MediaPlayer一直操作的是一个流媒体,所以无可避免的可能一段流媒体资源,前半段可以正常播放,而中间一段因为解析或者源文件错误等问题,造成中间一段无法播放问题,需要我们处理这个错误,否则会影响Ux(用户体验)。可以为MediaPlayer注册回调函数setOnErrorListener()来设置出错之后的解决办法,一般重新播放或者播放下一个流媒体即可。

自己用Kotlin写的一个音乐播放器(仿QQ音乐),算是MediaPlayer使用的一个小例子吧
https://github.com/neugaojin/SEMusic

推荐阅读更多精彩内容