android 使用mediaplayer播放网络音乐
16lz
2021-01-24
关于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); } }}
这个管理类实现了播放在线音频的功能,如果有什么问题,欢迎留言交流。
更多相关文章
- 真机上运行monkeyrunner python脚本踩坑系列一
- Android(安卓)定时任务过程详解
- Android(安卓)Studio如何设置自动import价包
- StatusBar (状态栏)的架构(Android(安卓)2.3)
- 百度也出手机操作系统
- Android――ContentProvider (一)创建contentProvider
- Android(安卓)使用librtmp推流【音视频传输】
- Android(安卓)针对View的截图操作
- Android(安卓)返回桌面的操作