android 使用mediaplayer播放网络音乐

关于mediaplayer 的介绍

MediaPlayer是Android自带的一个多媒体播放类,可以播放音视频流或者本地音视频文件。MediaPlayer方法的调用需要在一定的状态下,下图是一个MediaPlayer对象被支持的播放控制操作驱动的声明周期和状态。其中,椭圆代表MediaPlayer可能驻留的状态,弧线表示驱动MediaPlayer在各个状态之间迁移的播放控制操作。这里有两种类型的弧线。由单箭头开始的弧线代表同步方法调用,而以双箭头开头的弧线代表异步方法调用。图片介绍来源于官方文。
 

封装一个管理类,用于播放在线的音乐

由于播放在线音乐时可能会因为网络的原因,导致耗时比较大,这里使用了AndroidVideoCache这个库,来实现音频的缓存,下次再播放的时候就可以避免再次从网络获取。
AndroidVideoCache地址:https://github.com/danikula/AndroidVideoCache以下是封装的管理类的代码:
AudioManager.java

public class AudioManager implements MediaPlayer.OnPreparedListener,
MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener{

    private static AudioManager INSTANCE;

    private MediaPlayer mMediaPlayer;

    private Context mContext;

    /**
     * 是否正在准备
     */
    private boolean isPreparing = false;

    /**
     * 当前准备
     */
    private AudioBean preBean;

    private Handler mHandler;

    /**
     * 最后的一个操作,如果是prepareing的时候,所有操作都保存在这里
     */
    private AudioBean curBean;

    private AudioManager(Context context){
        this.mContext = context;
        initMediaPlayer();
        mHandler = new Handler(){
            @Override
            public void handleMessage(@NonNull Message msg) {
                preparing();
            }
        };
    }

    public static AudioManager getInstance(Context context){
        if (INSTANCE == null) {
            synchronized(AudioManager.class) {
                if (INSTANCE == null){
                    INSTANCE = new AudioManager(context);
                }
            }
        }
        return INSTANCE;
    }

    /**
     * 播放Assest目录下的音频
     * @param name
     */
    public void playAssertAudio(String name) {
        if(mMediaPlayer != null && mContext != null) {
            try {
                mMediaPlayer.reset();
                AssetFileDescriptor fd = mContext.getAssets().openFd(name);
                mMediaPlayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
                mMediaPlayer.prepareAsync();
                mMediaPlayer.setOnPreparedListener(this);
                mMediaPlayer.setOnCompletionListener(this);

                mMediaPlayer.setOnErrorListener(this);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 停止播放
     */
    protected void stopAssertAudio() {
        if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
            mMediaPlayer.stop();
            Toast.makeText(mContext, "停止播放", Toast.LENGTH_SHORT).show();
        }
    }


    /**
     * 播放音频
     * @param url
     */
    public void playAudio(final String url) {
        if(isPreparing) {
            setCurdata(url, AudioBean.START, true);
            return ;
        }
        if(mMediaPlayer != null && mContext != null) {
            try {
                setPredata(url, AudioBean.START, true);

                mMediaPlayer.reset();
                HttpProxyCacheServer proxy = HttpProxyCacheUtil.getAudioProxy(mContext);
                mMediaPlayer.setDataSource(proxy.getProxyUrl(url));
                isPreparing = true;
                mMediaPlayer.prepareAsync();
                mMediaPlayer.setOnPreparedListener(this);
                mMediaPlayer.setOnCompletionListener(this);

                mMediaPlayer.setOnErrorListener(this);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 释放MediaPlayer
     */
    public void clear() {
        if (mMediaPlayer != null) {
            if(mMediaPlayer.isPlaying())
                mMediaPlayer.stop();
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
    }

    /**
     * 停止播放
     */
    public void stopAudio(String url) {
        if(isPreparing) { // 如果mediaplayer当前正在准备数据,则只保留数据
            setCurdata(url, AudioBean.STOP, true);
        } else {
            if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
                mMediaPlayer.stop();
            }
        }
    }

    /**
     * 准备播放
     */
    @Override
    public void onPrepared(MediaPlayer mp) {
        mHandler.sendEmptyMessageDelayed(1, 0); // 模拟mediaplayer准备数据中间时长,延时
    }

    private void preparing() {
        isPreparing = false;
        if(preBean != null && curBean != null && curBean.isNeed()) { // 需要处理
            // 判断url是否一样,
            if(preBean.getUrl().equals(curBean.getUrl())) { // 比如点击暂停,又点击开始
                if(curBean.getStatus() == AudioBean.START && curBean.isNeed()) { // 如果同一个url并且需要播放,就直接start,比如prepare的时候,点击了暂停,在点击开始,同一个音频
                    start();
                } else { // 同一个url,如果是停止,就直接不处理,后面把isNeed设置成false
                }
            } else { // 如果不同url,说明点击了另外的音频,
                if(curBean.getStatus() == AudioBean.START && curBean.isNeed()) { // 重新play新的url
                    playAudio(curBean.getUrl());
                } else { // 如果停止的话无需处理
                }
            }
            setCurdata("", AudioBean.STOP, false);
        } else { // 如果最后一次操作不需要处理,则走正常流程
            start();
        }
    }

    /**
     * 完成
     */
    @Override
    public void onCompletion(MediaPlayer mp) {
    }

    /**
     * 播放错误
     */
    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        return false;
    }

    /**
     * init
     */
    private void initMediaPlayer() {
        if(mMediaPlayer != null) {
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
        mMediaPlayer = new MediaPlayer();
        mMediaPlayer.setAudioStreamType(android.media.AudioManager.STREAM_MUSIC);
    }

    /**
     * 开始播放
     */
    private void start() {
        if (mMediaPlayer != null)
            mMediaPlayer.start();
    }

    /**
     * 保存prepare前的操作
     */
    private void setPredata(String url, int status, boolean isNeed) {
        if(preBean == null) {
            preBean = new AudioBean();
        }
        if(preBean != null) {
            preBean.setUrl(url);
            preBean.setStatus(status);
            preBean.setNeed(isNeed);
        }
    }

    /**
     * 保存prepare中的操作
     */
    private void setCurdata(String url, int status, boolean isNeed) {
        if(curBean == null) {
            curBean = new AudioBean();
        }
        if(curBean != null) {
            curBean.setUrl(url);
            curBean.setStatus(status);
            curBean.setNeed(isNeed);
        }
    }


}

这个管理类实现了播放在线音频的功能,如果有什么问题,欢迎留言交流。

你可能感兴趣的:(android)