关于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);
}
}
}
这个管理类实现了播放在线音频的功能,如果有什么问题,欢迎留言交流。