CustomPlayer.java 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. package com.cooleshow.musicmerge.player;
  2. import android.content.Context;
  3. import android.media.AudioManager;
  4. import android.media.MediaPlayer;
  5. import android.media.PlaybackParams;
  6. import android.net.Uri;
  7. import android.os.Handler;
  8. import android.os.Looper;
  9. import android.os.Message;
  10. import android.util.Log;
  11. import android.view.Surface;
  12. import android.view.SurfaceHolder;
  13. import com.cooleshow.base.utils.LOG;
  14. import java.io.IOException;
  15. import androidx.annotation.NonNull;
  16. /**
  17. * Author by pq, Date on 2023/5/11.
  18. */
  19. public class CustomPlayer implements MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnVideoSizeChangedListener {
  20. public String TAG = "";
  21. public static final int RESUME_PLAY_MSG_WHAT = 10001;
  22. private Context mContext;
  23. MediaPlayer mPlayer;
  24. private boolean hasPrepared;
  25. private boolean isStoped = false;
  26. private AudioManager mAudioManager;
  27. private OnEventListener onEventListener;
  28. public CustomPlayer(String tag) {
  29. TAG = tag;
  30. }
  31. private Handler mHandler = new Handler(Looper.getMainLooper()) {
  32. @Override
  33. public void handleMessage(@NonNull Message msg) {
  34. int what = msg.what;
  35. if (what == RESUME_PLAY_MSG_WHAT) {
  36. expectPosition = 0;
  37. resume();
  38. return;
  39. }
  40. }
  41. };
  42. private Runnable progressRunnable = new Runnable() {
  43. @Override
  44. public void run() {
  45. if (mPlayer != null) {
  46. int currentPosition = mPlayer.getCurrentPosition();
  47. if (onEventListener != null) {
  48. onEventListener.onProgress(currentPosition);
  49. }
  50. sendProgressMsg();
  51. }
  52. }
  53. };
  54. public CustomPlayer() {
  55. initPlayer();
  56. }
  57. private void initPlayer() {
  58. if (null == mPlayer) {
  59. mPlayer = new MediaPlayer();
  60. mPlayer.setOnErrorListener(this);
  61. mPlayer.setOnCompletionListener(this);
  62. mPlayer.setOnPreparedListener(this);
  63. mPlayer.setOnVideoSizeChangedListener(this);
  64. }
  65. }
  66. public MediaPlayer getPlayer() {
  67. return mPlayer;
  68. }
  69. public void setVolume(float volume) {
  70. if (mPlayer != null) {
  71. LOG.i("setVolume:" + volume + "hasPrepared:" + hasPrepared);
  72. mPlayer.setVolume(volume, volume);
  73. }
  74. }
  75. public void play(Context context, Uri dataSource) {
  76. hasPrepared = false; // 开始播放前讲Flag置为不可操作
  77. isStoped = false;
  78. initPlayer(); // 如果是第一次播放/player已经释放了,就会重新创建、初始化
  79. try {
  80. removeAllMsg();
  81. mPlayer.reset();
  82. mPlayer.setDataSource(context, dataSource); // 设置曲目资源
  83. mPlayer.prepareAsync(); // 异步的准备方法
  84. } catch (IOException e) {
  85. e.printStackTrace();
  86. }
  87. }
  88. public void play(String path) {
  89. hasPrepared = false; // 开始播放前讲Flag置为不可操作
  90. isStoped = false; //
  91. initPlayer(); // 如果是第一次播放/player已经释放了,就会重新创建、初始化
  92. try {
  93. removeAllMsg();
  94. mPlayer.reset();
  95. mPlayer.setDataSource(path); // 设置曲目资源
  96. mPlayer.prepareAsync(); // 异步的准备方法
  97. } catch (IOException e) {
  98. e.printStackTrace();
  99. }
  100. }
  101. public int getCu() {
  102. try {
  103. if (mPlayer != null) {
  104. int currentPosition = mPlayer.getCurrentPosition();
  105. return currentPosition;
  106. }
  107. } catch (Exception e) {
  108. e.printStackTrace();
  109. }
  110. return 0;
  111. }
  112. public int getT() {
  113. if (mPlayer != null) {
  114. int duration = mPlayer.getDuration();
  115. return duration;
  116. }
  117. return -1;
  118. }
  119. public void start() {
  120. if (isStoped) {
  121. return;
  122. }
  123. // release()会释放player、将player置空,所以这里需要判断一下
  124. if (null != mPlayer && hasPrepared) {
  125. LOG.i(TAG, "start expectPosition:" + expectPosition);
  126. if (expectPosition < 0) {
  127. sendDelayPlayMsg(Math.abs(expectPosition));
  128. return;
  129. }
  130. mPlayer.start();
  131. }
  132. // // release()会释放player、将player置空,所以这里需要判断一下
  133. // if (null != mPlayer && hasPrepared) {
  134. // mPlayer.start();
  135. // }
  136. }
  137. public void setSpeed(float speed) {
  138. if (speed < 0.5 || speed > 2.0f) {
  139. return;
  140. }
  141. try {
  142. if (mPlayer != null) {
  143. if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
  144. PlaybackParams playbackParams = mPlayer.getPlaybackParams();
  145. LOG.i("pq", "setSpeed:" + speed);
  146. playbackParams.setSpeed(speed);
  147. mPlayer.setPlaybackParams(playbackParams);
  148. }
  149. }
  150. } catch (Exception e) {
  151. e.printStackTrace();
  152. }
  153. }
  154. public void pause() {
  155. if (null != mPlayer && hasPrepared) {
  156. mPlayer.pause();
  157. }
  158. }
  159. public void resume() {
  160. if (null != mPlayer && hasPrepared) {
  161. LOG.i(TAG, "resume expectPosition:" + expectPosition);
  162. if (expectPosition < 0) {
  163. sendDelayPlayMsg(Math.abs(expectPosition));
  164. return;
  165. }
  166. mPlayer.start();
  167. }
  168. }
  169. private int expectPosition = 0;
  170. public int getExpectPosition() {
  171. return expectPosition;
  172. }
  173. public void setExpectPosition(int expectPosition) {
  174. this.expectPosition = expectPosition;
  175. }
  176. public void resetToPrepare() {
  177. if (expectPosition == 0) {
  178. seekTo(0);
  179. } else {
  180. seekTo(expectPosition);
  181. }
  182. }
  183. public void seekTo(int position) {
  184. this.expectPosition = position;
  185. LOG.i(TAG, "seekTo expectPosition:" + expectPosition);
  186. if (mPlayer == null) {
  187. return;
  188. }
  189. mHandler.removeMessages(RESUME_PLAY_MSG_WHAT);
  190. LOG.i(TAG, "seekTo getTotal:" + getTotal());
  191. if (position > getTotal()) {
  192. position = getTotal();
  193. }
  194. LOG.i(TAG, "isPlaying:" + isPlaying());
  195. if (position < 0) {
  196. mPlayer.seekTo(0);
  197. if (isPlaying()) {
  198. pause();
  199. sendDelayPlayMsg(Math.abs(position));
  200. }
  201. return;
  202. }
  203. LOG.i(TAG, "seekTo:" + position + "--hasPrepared:" + hasPrepared);
  204. if (null != mPlayer && hasPrepared) {
  205. mPlayer.seekTo(position);
  206. }
  207. }
  208. private void sendDelayPlayMsg(int delay) {
  209. LOG.i(TAG,"sendDelayPlayMsg:"+delay);
  210. Message obtain = Message.obtain();
  211. obtain.what = RESUME_PLAY_MSG_WHAT;
  212. mHandler.removeMessages(RESUME_PLAY_MSG_WHAT);
  213. mHandler.sendMessageDelayed(obtain, delay);
  214. }
  215. // 对于播放视频来说,通过设置SurfaceHolder来设置显示Surface。这个方法不需要判断状态、也不会改变player状态
  216. public void setDisplay(SurfaceHolder holder) {
  217. if (null != mPlayer) {
  218. mPlayer.setDisplay(holder);
  219. }
  220. }
  221. public boolean isPlaying() {
  222. if (null != mPlayer) {
  223. return mPlayer.isPlaying();
  224. }
  225. return false;
  226. }
  227. public void release() {
  228. removeAllMsg();
  229. hasPrepared = false;
  230. isStoped = true;
  231. if (mPlayer != null) {
  232. mPlayer.stop();
  233. mPlayer.release();
  234. mPlayer = null;
  235. }
  236. }
  237. public void stop() {
  238. if (mPlayer == null) {
  239. return;
  240. }
  241. removeAllMsg();
  242. isStoped = true;
  243. hasPrepared = false;
  244. Log.i(TAG, "player to stop:" + hasPrepared + "-thread:" + Thread.currentThread().getName());
  245. mPlayer.stop();
  246. }
  247. @Override
  248. public void onPrepared(MediaPlayer mp) {
  249. hasPrepared = true; // 准备完成后回调到这里
  250. sendProgressMsg();
  251. if (onEventListener != null) {
  252. onEventListener.onPrepared(getTotal());
  253. }
  254. }
  255. public int getTotal() {
  256. if (mPlayer != null) {
  257. return mPlayer.getDuration();
  258. }
  259. return 0;
  260. }
  261. private void sendProgressMsg() {
  262. mHandler.postDelayed(progressRunnable, 100);
  263. }
  264. private void removeAllMsg() {
  265. mHandler.removeCallbacksAndMessages(null);
  266. }
  267. @Override
  268. public void onCompletion(MediaPlayer mp) {
  269. // hasPrepared = false;
  270. if (onEventListener != null) {
  271. onEventListener.onCompleted();
  272. }
  273. // 通知调用处,调用play()方法进行下一个曲目的播放
  274. }
  275. @Override
  276. public boolean onError(MediaPlayer mp, int what, int extra) {
  277. hasPrepared = false;
  278. if (onEventListener != null) {
  279. onEventListener.onError();
  280. }
  281. return true;
  282. }
  283. public void setOnEventListener(OnEventListener onEventListener) {
  284. this.onEventListener = onEventListener;
  285. }
  286. @Override
  287. public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
  288. if (onEventListener != null) {
  289. onEventListener.onVideoSizeChanged(mp, width, height);
  290. }
  291. }
  292. public interface OnEventListener {
  293. void onProgress(int progress);
  294. void onPrepared(int duration);
  295. void onCompleted();
  296. void onError();
  297. void onVideoSizeChanged(MediaPlayer mp, int width, int height);
  298. }
  299. public void setSurface(SurfaceHolder sh) {
  300. if (mPlayer != null) {
  301. mPlayer.setDisplay(sh);
  302. }
  303. }
  304. public void setSurface(Surface sh) {
  305. if (mPlayer != null) {
  306. mPlayer.setSurface(sh);
  307. }
  308. }
  309. }