關於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);
}
}
}
這個管理類實現了播放在線音頻的功能,如果有什麼問題,歡迎留言交流。