package com.cooleshow.musicmerge.player; import android.content.Context; import android.media.AudioManager; import android.media.MediaPlayer; import android.media.PlaybackParams; import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.util.Log; import android.view.Surface; import android.view.SurfaceHolder; import com.cooleshow.base.utils.LOG; import java.io.IOException; import androidx.annotation.NonNull; /** * Author by pq, Date on 2023/5/11. */ public class CustomPlayer implements MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnVideoSizeChangedListener { public String TAG = ""; public static final int RESUME_PLAY_MSG_WHAT = 10001; private Context mContext; MediaPlayer mPlayer; private boolean hasPrepared; private boolean isStoped = false; private AudioManager mAudioManager; private OnEventListener onEventListener; public CustomPlayer(String tag) { TAG = tag; } private Handler mHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(@NonNull Message msg) { int what = msg.what; if (what == RESUME_PLAY_MSG_WHAT) { expectPosition = 0; resume(); return; } } }; private Runnable progressRunnable = new Runnable() { @Override public void run() { if (mPlayer != null) { int currentPosition = mPlayer.getCurrentPosition(); if (onEventListener != null) { onEventListener.onProgress(currentPosition); } sendProgressMsg(); } } }; public CustomPlayer() { initPlayer(); } private void initPlayer() { if (null == mPlayer) { mPlayer = new MediaPlayer(); mPlayer.setOnErrorListener(this); mPlayer.setOnCompletionListener(this); mPlayer.setOnPreparedListener(this); mPlayer.setOnVideoSizeChangedListener(this); } } public MediaPlayer getPlayer() { return mPlayer; } public void setVolume(float volume) { if (mPlayer != null) { LOG.i("setVolume:" + volume + "hasPrepared:" + hasPrepared); mPlayer.setVolume(volume, volume); } } public void play(Context context, Uri dataSource) { hasPrepared = false; // 开始播放前讲Flag置为不可操作 isStoped = false; initPlayer(); // 如果是第一次播放/player已经释放了,就会重新创建、初始化 try { removeAllMsg(); mPlayer.reset(); mPlayer.setDataSource(context, dataSource); // 设置曲目资源 mPlayer.prepareAsync(); // 异步的准备方法 } catch (IOException e) { e.printStackTrace(); } } public void play(String path) { hasPrepared = false; // 开始播放前讲Flag置为不可操作 isStoped = false; // initPlayer(); // 如果是第一次播放/player已经释放了,就会重新创建、初始化 try { removeAllMsg(); mPlayer.reset(); mPlayer.setDataSource(path); // 设置曲目资源 mPlayer.prepareAsync(); // 异步的准备方法 } catch (IOException e) { e.printStackTrace(); } } public int getCu() { try { if (mPlayer != null) { int currentPosition = mPlayer.getCurrentPosition(); return currentPosition; } } catch (Exception e) { e.printStackTrace(); } return 0; } public int getT() { if (mPlayer != null) { int duration = mPlayer.getDuration(); return duration; } return -1; } public void start() { if (isStoped) { return; } // release()会释放player、将player置空,所以这里需要判断一下 if (null != mPlayer && hasPrepared) { LOG.i(TAG, "start expectPosition:" + expectPosition); if (expectPosition < 0) { sendDelayPlayMsg(Math.abs(expectPosition)); return; } mPlayer.start(); } // // release()会释放player、将player置空,所以这里需要判断一下 // if (null != mPlayer && hasPrepared) { // mPlayer.start(); // } } public void setSpeed(float speed) { if (speed < 0.5 || speed > 2.0f) { return; } try { if (mPlayer != null) { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { PlaybackParams playbackParams = mPlayer.getPlaybackParams(); LOG.i("pq", "setSpeed:" + speed); playbackParams.setSpeed(speed); mPlayer.setPlaybackParams(playbackParams); } } } catch (Exception e) { e.printStackTrace(); } } public void pause() { if (null != mPlayer && hasPrepared) { mPlayer.pause(); } } public void resume() { if (null != mPlayer && hasPrepared) { LOG.i(TAG, "resume expectPosition:" + expectPosition); if (expectPosition < 0) { sendDelayPlayMsg(Math.abs(expectPosition)); return; } mPlayer.start(); } } private int expectPosition = 0; public int getExpectPosition() { return expectPosition; } public void setExpectPosition(int expectPosition) { this.expectPosition = expectPosition; } public void resetToPrepare() { if (expectPosition == 0) { seekTo(0); } else { seekTo(expectPosition); } } public void seekTo(int position) { this.expectPosition = position; LOG.i(TAG, "seekTo expectPosition:" + expectPosition); if (mPlayer == null) { return; } mHandler.removeMessages(RESUME_PLAY_MSG_WHAT); LOG.i(TAG, "seekTo getTotal:" + getTotal()); if (position > getTotal()) { position = getTotal(); } LOG.i(TAG, "isPlaying:" + isPlaying()); if (position < 0) { mPlayer.seekTo(0); if (isPlaying()) { pause(); sendDelayPlayMsg(Math.abs(position)); } return; } LOG.i(TAG, "seekTo:" + position + "--hasPrepared:" + hasPrepared); if (null != mPlayer && hasPrepared) { mPlayer.seekTo(position); } } private void sendDelayPlayMsg(int delay) { LOG.i(TAG,"sendDelayPlayMsg:"+delay); Message obtain = Message.obtain(); obtain.what = RESUME_PLAY_MSG_WHAT; mHandler.removeMessages(RESUME_PLAY_MSG_WHAT); mHandler.sendMessageDelayed(obtain, delay); } // 对于播放视频来说,通过设置SurfaceHolder来设置显示Surface。这个方法不需要判断状态、也不会改变player状态 public void setDisplay(SurfaceHolder holder) { if (null != mPlayer) { mPlayer.setDisplay(holder); } } public boolean isPlaying() { if (null != mPlayer) { return mPlayer.isPlaying(); } return false; } public void release() { removeAllMsg(); hasPrepared = false; isStoped = true; if (mPlayer != null) { mPlayer.stop(); mPlayer.release(); mPlayer = null; } } public void stop() { if (mPlayer == null) { return; } removeAllMsg(); isStoped = true; hasPrepared = false; Log.i(TAG, "player to stop:" + hasPrepared + "-thread:" + Thread.currentThread().getName()); mPlayer.stop(); } @Override public void onPrepared(MediaPlayer mp) { hasPrepared = true; // 准备完成后回调到这里 sendProgressMsg(); if (onEventListener != null) { onEventListener.onPrepared(getTotal()); } } public int getTotal() { if (mPlayer != null) { return mPlayer.getDuration(); } return 0; } private void sendProgressMsg() { mHandler.postDelayed(progressRunnable, 100); } private void removeAllMsg() { mHandler.removeCallbacksAndMessages(null); } @Override public void onCompletion(MediaPlayer mp) { // hasPrepared = false; if (onEventListener != null) { onEventListener.onCompleted(); } // 通知调用处,调用play()方法进行下一个曲目的播放 } @Override public boolean onError(MediaPlayer mp, int what, int extra) { hasPrepared = false; if (onEventListener != null) { onEventListener.onError(); } return true; } public void setOnEventListener(OnEventListener onEventListener) { this.onEventListener = onEventListener; } @Override public void onVideoSizeChanged(MediaPlayer mp, int width, int height) { if (onEventListener != null) { onEventListener.onVideoSizeChanged(mp, width, height); } } public interface OnEventListener { void onProgress(int progress); void onPrepared(int duration); void onCompleted(); void onError(); void onVideoSizeChanged(MediaPlayer mp, int width, int height); } public void setSurface(SurfaceHolder sh) { if (mPlayer != null) { mPlayer.setDisplay(sh); } } public void setSurface(Surface sh) { if (mPlayer != null) { mPlayer.setSurface(sh); } } }