美文网首页Android开发
Android MediaPlayer的封装

Android MediaPlayer的封装

作者: 一个冬季 | 来源:发表于2019-06-24 14:38 被阅读0次
    注意

    本文封装是在android音视频指南-MediaPlayer概述上进行的2次开发。二次封装完成后,我提供了正在播放、暂停播放、重置、播放完成、媒体流装载完成、媒体流加载中、异常错误等的状态返回

    业务需求

    需要对音乐媒体类进行播放,如果需要播放的音乐本地缓存没有,需要先下载,然后加载音乐。如果有本地缓存的音乐,直接从本地缓存里面读取,然后加载最后播放

    使用说明

    1、你需要在自己的Activity或者Fragment去 implements PlaybackInfoListener 接口

    MediaPlayerHolder mediaPlayerIngHolder = new MediaPlayerHolder();
    mediaPlayerIngHolder.setmPlaybackInfoListener(this);//设置监听
    

    2、如果是要加载网络音乐(我建议先下载下来),或者是本地音乐,需要调用

    mediaPlayerIngHolder.loadMedia(path);//加载音乐,不是属于播放的状态
    mediaPlayerIngHolder.play();//开始播放,注意:需要等到onStateChanged == PLAYSTATUS4才可以调用这个方法
    

    3、如果不需要播放了,需要释放资源

     mediaPlayerIngHolder.release();
     mediaPlayerIngHolder = null;
    
    接口回调说明
     void onDurationChanged(int duration);//返回音乐的总时长
     void onPositionChanged(int position);//当播放的进度
     void onStateChanged(int state);//记录当前的状态
     void onPlaybackCompleted();//播放完成回调
    
    学习总结

    1、每次调用mediaPlayerIngHolder.loadMedia方法,都需要 mMediaPlayer.reset(),这样是防止再次添加进来出现崩溃信息
    2、为了避免阻塞主线程,预加载音乐需要使用mMediaPlayer.prepareAsync();预加载完成才可以使用mMediaPlayer.start();播放音乐

    代码展示
    /**
    * @date: 2019/6/21 0021
    * @author: gaoxiaoxiong
    * @description:播放回调
    **/
    public interface PlaybackInfoListener {
        void onDurationChanged(int duration);//总时长
    
        void onPositionChanged(int position);//当前时长进度
    
        void onStateChanged(int state);//记录当前的状态
    
        void onPlaybackCompleted();//播放完成回调
    }
    
    
    public interface PlayerAdapterListener {
        void loadMedia(String musiUrl);//加载媒体资源
    
        void release();//释放资源
    
        boolean isPlaying();//判断是否在播放
    
        void play();//开始播放
    
        void reset();//重置
    
        void pause();//暂停
    
        void medisaPreparedCompled();//完成媒体流的装载
    
        void seekTo(int position);//滑动到某个位置
    }
    
    
    public class MediaPlayerHolder implements PlayerAdapterListener{
        public static int PLAYSTATUS0=0;//正在播放
        public static int PLAYSTATUS1=1;//暂停播放
        public static int PLAYSTATUS2=2;//重置
        public static int PLAYSTATUS3=3;//播放完成
        public static int PLAYSTATUS4=4;//媒体流装载完成
        public static int PLAYSTATUS5=5;//媒体流加载中
        public static int PLAYSTATUSD1=-1;//错误
    
        public int PLAYBACK_POSITION_REFRESH_INTERVAL_MS = 1000;
        private String TAG = MediaPlayerHolder.class.getSimpleName();
        private MediaPlayer mMediaPlayer;
        private ScheduledExecutorService mExecutor;//开启线程
        private PlaybackInfoListener mPlaybackInfoListener;
        private Runnable mSeekbarPositionUpdateTask;
        private String musiUrl;//音乐地址,可以是本地的音乐,可以是网络的音乐
    
    
        public void setmPlaybackInfoListener(PlaybackInfoListener mPlaybackInfoListener) {
            this.mPlaybackInfoListener = mPlaybackInfoListener;
        }
    
    
        /**
        * @date: 2019/6/21 0021
        * @author: gaoxiaoxiong
        * @description:初始化MediaPlayer
        **/
        private void initializeMediaPlayer(){
            if (mMediaPlayer == null) {
                mMediaPlayer = new MediaPlayer();
                //注册,播放完成后的监听
                mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                    @Override
                    public void onCompletion(MediaPlayer mediaPlayer) {
                        stopUpdatingCallbackWithPosition(true);
                        if (mPlaybackInfoListener != null) {
                            mPlaybackInfoListener.onStateChanged(PLAYSTATUS3);
                            mPlaybackInfoListener.onPlaybackCompleted();
                        }
                    }
                });
    
                //监听媒体流是否装载完成
                mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        medisaPreparedCompled();
                    }
                });
    
                /**
                * @date: 2019/6/21 0021
                * @author: gaoxiaoxiong
                * @description:监听媒体错误信息
                **/
                mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                    @Override
                    public boolean onError(MediaPlayer mp, int what, int extra) {
                        if (mPlaybackInfoListener!=null){
                            mPlaybackInfoListener.onStateChanged(PLAYSTATUSD1);
                        }
                        Log.d(TAG, "OnError - Error code: " + what + " Extra code: " + extra);
                        switch (what) {
                            case -1004:
                                Log.d(TAG, "MEDIA_ERROR_IO");
                                break;
                            case -1007:
                                Log.d(TAG, "MEDIA_ERROR_MALFORMED");
                                break;
                            case 200:
                                Log.d(TAG, "MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK");
                                break;
                            case 100:
                                Log.d(TAG, "MEDIA_ERROR_SERVER_DIED");
                                break;
                            case -110:
                                Log.d(TAG, "MEDIA_ERROR_TIMED_OUT");
                                break;
                            case 1:
                                Log.d(TAG, "MEDIA_ERROR_UNKNOWN");
                                break;
                            case -1010:
                                Log.d(TAG, "MEDIA_ERROR_UNSUPPORTED");
                                break;
                        }
                        switch (extra) {
                            case 800:
                                Log.d(TAG, "MEDIA_INFO_BAD_INTERLEAVING");
                                break;
                            case 702:
                                Log.d(TAG, "MEDIA_INFO_BUFFERING_END");
                                break;
                            case 701:
                                Log.d(TAG, "MEDIA_INFO_METADATA_UPDATE");
                                break;
                            case 802:
                                Log.d(TAG, "MEDIA_INFO_METADATA_UPDATE");
                                break;
                            case 801:
                                Log.d(TAG, "MEDIA_INFO_NOT_SEEKABLE");
                                break;
                            case 1:
                                Log.d(TAG, "MEDIA_INFO_UNKNOWN");
                                break;
                            case 3:
                                Log.d(TAG, "MEDIA_INFO_VIDEO_RENDERING_START");
                                break;
                            case 700:
                                Log.d(TAG, "MEDIA_INFO_VIDEO_TRACK_LAGGING");
                                break;
                        }
                        return false;
                    }
                });
            }
        }
    
        /**
        * @date: 2019/6/24 0024
        * @author: gaoxiaoxiong
        * @description: 加载媒体资源
        **/
        @Override
        public void loadMedia(String musiUrl) {
            if (StringUtils.getInstance().isEmpty(musiUrl)){
                Log.i(TAG,"地址为空");
                return;
            }
    
            if (mPlaybackInfoListener!=null){
                mPlaybackInfoListener.onStateChanged(PLAYSTATUS5);
            }
    
            this.musiUrl = musiUrl;
            initializeMediaPlayer();
            try {
                mMediaPlayer.reset();//防止再次添加进来出现崩溃信息
                mMediaPlayer.setDataSource(musiUrl);
                mMediaPlayer.prepareAsync();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        /**
        * @date: 2019/6/24 0024
        * @author: gaoxiaoxiong
        * @description:释放媒体资源
        **/
        @Override
        public void release() {
            if (mMediaPlayer != null) {
                stopUpdatingCallbackWithPosition(false);
                mMediaPlayer.stop();
                mMediaPlayer.release();
                mMediaPlayer = null;
            }
        }
    
        /**
        * @date: 2019/6/24 0024
        * @author: gaoxiaoxiong
        * @description:判断是否正在播放
        **/
        @Override
        public boolean isPlaying() {
            if (mMediaPlayer != null) {
                return mMediaPlayer.isPlaying();
            }
            return false;
        }
    
        /**
        * @date: 2019/6/24 0024
        * @author: gaoxiaoxiong
        * @description:播放开始
        **/
        @Override
        public void play() {
            if (mMediaPlayer != null && !mMediaPlayer.isPlaying()) {
                mMediaPlayer.start();
                if (mPlaybackInfoListener != null) {
                    mPlaybackInfoListener.onStateChanged(PLAYSTATUS0);
                }
                startUpdatingCallbackWithPosition();
            }
        }
    
        /**
        * @date: 2019/6/21 0021
        * @author: gaoxiaoxiong
        * @description:开启线程,获取当前播放的进度
        **/
        private void startUpdatingCallbackWithPosition() {
            if (mExecutor == null) {
                mExecutor = Executors.newSingleThreadScheduledExecutor();
            }
            if (mSeekbarPositionUpdateTask == null) {
                mSeekbarPositionUpdateTask = new Runnable() {
                    @Override
                    public void run() {
                        updateProgressCallbackTask();
                    }
                };
            }
    
            mExecutor.scheduleAtFixedRate(
                    mSeekbarPositionUpdateTask,
                    0,
                    PLAYBACK_POSITION_REFRESH_INTERVAL_MS,
                    TimeUnit.MILLISECONDS
            );
        }
    
        @Override
        public void reset() {
            if (mMediaPlayer != null) {
                loadMedia(musiUrl);
                if (mPlaybackInfoListener != null) {
                    mPlaybackInfoListener.onStateChanged(PLAYSTATUS2);
                }
                stopUpdatingCallbackWithPosition(true);
            }
        }
    
        /**
        * @date: 2019/6/24 0024
        * @author: gaoxiaoxiong
        * @description:暂停
        **/
        @Override
        public void pause() {
            if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
                mMediaPlayer.pause();
                if (mPlaybackInfoListener != null) {
                    mPlaybackInfoListener.onStateChanged(PLAYSTATUS1);
                }
            }
        }
    
        /**
        * @date: 2019/6/21 0021
        * @author: gaoxiaoxiong
        * @description:更新当前的进度
        **/
        private void updateProgressCallbackTask() {
            if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
                int currentPosition = mMediaPlayer.getCurrentPosition();
                if (mPlaybackInfoListener != null) {
                    mPlaybackInfoListener.onPositionChanged(currentPosition);
                }
            }
        }
    
        /**
        * @date: 2019/6/24 0024
        * @author: gaoxiaoxiong
        * @description:加载完成回调
        **/
        @Override
        public void medisaPreparedCompled() {
            int duration = mMediaPlayer.getDuration();//获取总时长
            if (mPlaybackInfoListener != null) {
                mPlaybackInfoListener.onDurationChanged(duration);
                mPlaybackInfoListener.onPositionChanged(0);
                mPlaybackInfoListener.onStateChanged(PLAYSTATUS4);
            }
        }
    
        /**
         * @date: 2019/6/21 0021
         * @author: gaoxiaoxiong
         * @description:滑动播放到某个位置
         **/
        @Override
        public void seekTo(int position) {
            if (mMediaPlayer != null) {
                mMediaPlayer.seekTo(position);
            }
        }
    
    
        /**
        * @date: 2019/6/21 0021
        * @author: gaoxiaoxiong
        * @description:播放完成回调监听
        **/
        private void stopUpdatingCallbackWithPosition(boolean resetUIPlaybackPosition) {
            if (mExecutor != null) {
                mExecutor.shutdownNow();
                mExecutor = null;
                mSeekbarPositionUpdateTask = null;
                if (resetUIPlaybackPosition && mPlaybackInfoListener != null) {
                    mPlaybackInfoListener.onPositionChanged(0);
                }
            }
        }
    }
    
    

    相关文章

      网友评论

        本文标题:Android MediaPlayer的封装

        本文链接:https://www.haomeiwen.com/subject/krbnqctx.html