mediaplayer 正确使用
package com.github.jasonhancn.tvcursor.util;
import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.SurfaceHolder;
import com.realtop.mqttutils.MUtils;
public class NativePlayer {
private static final String TAG = "NativePlayer";
private final Handler handler;
private final Runnable videoNextAction;
private final String path;
private final SurfaceHolder mSurfaceHolder;
private final AudioManager audioManager;
private final Context context;
private final long fireTime;
private final String ip;
private MediaPlayer mediaPlayer;
private boolean isPrepared;
private boolean isCloseByUser;
private long start;
public static final int open_audio_delay = 288;
public NativePlayer(Runnable videoNextAction, String path, SurfaceHolder mSurfaceHolder, AudioManager audioManager, Context context, long fireTime, String ip) {
this.videoNextAction = videoNextAction;
this.path = path;
this.mSurfaceHolder = mSurfaceHolder;
this.audioManager = audioManager;
this.context = context;
this.fireTime = fireTime;
this.ip = ip;
this.handler = new Handler(Looper.getMainLooper());
IjkInit();
}
public void IjkInit() {
if (mediaPlayer != null) return;
start = System.currentTimeMillis();
try {
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(path);
Log.i(TAG, "IjkInit: player video path:" + path);
if (mSurfaceHolder != null) mediaPlayer.setDisplay(mSurfaceHolder);
mediaPlayer.setOnPreparedListener(iMediaPlayer -> handler.post(this::onPrepareCallback));
mediaPlayer.setOnCompletionListener(iMediaPlayer -> handler.post(this::onCompleteCallback));
mediaPlayer.setOnErrorListener((iMediaPlayer, i, code) -> {
handler.post(() -> one rrorCallback(i, "error code:" + code));
return true;
});
mediaPlayer.prepareAsync();
} catch (Exception e) {
final String errorMsg = e.getMessage();
handler.post(() -> one rrorCallback(-118, errorMsg));
}
// 定时触发音量和同步
timeTriggerVideoPlay(fireTime, ip);
}
private boolean isEnterPrepare = false;
private void onPrepareCallback() {
isPrepared = true;
// 准备好前已经人工停止了
if (isCloseByUser) {
Log.i(TAG, "onPrepareCallback: user close media play:" + mediaPlayer);
IjkRelease();
return;
}
if (isEnterPrepare) {
Log.i(TAG, "onPrepareCallback: again enter prepare");
return;
}
isEnterPrepare = true;
// 开始后面播放
mediaPlayer.setVolume(0f, 0f);
mediaPlayer.start();
Log.i(TAG, "onPrepareCallback: prepare cost time:" + (System.currentTimeMillis() - start) + "; is playing:" + mediaPlayer.isPlaying());
}
private boolean isEnterComplete = false;
private void onCompleteCallback() {
isPrepared = true;
if (isEnterComplete) {
Log.i(TAG, "onCompleteCallback: again enter");
return;
}
isEnterComplete = true;
IjkRelease();
handler.post(videoNextAction);
Log.i(TAG, "completeCallback: video player end:" + (System.currentTimeMillis() - start) / 1000);
}
private boolean isEnterError = false;
private void one rrorCallback(int i, String msg) {
isPrepared = true;
if (isEnterError) {
Log.i(TAG, "onErrorCallback: again enter");
return;
}
isEnterError = true;
IjkRelease();
handler.post(videoNextAction);
Log.i(TAG, "errorCallback: play error code:" + i + "; use time:" + (System.currentTimeMillis() - start) / 1000);
MUtils.showMsg(context, "Video play failure ! error code:" + i + "; msg:" + msg);
}
public void handleClose() {
isCloseByUser = true;
IjkRelease();
}
public void IjkRelease() {
handler.removeCallbacksAndMessages(null);
Log.i(TAG, "IjkRelease: enter: isPrepared:" + isPrepared
+ "; isCloseByUser:" + isCloseByUser + "; media player:" + mediaPlayer);
if (!isPrepared) {
Log.i(TAG, "IjkRelease: player is not prepare");
return;
}
if (mediaPlayer != null) {
try {
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
Log.i(TAG, "IjkRelease: enter stop player");
}
} catch (Exception e) {
Log.i(TAG, "IjkRelease: pause error:" + e.getMessage());
}
try {
mediaPlayer.setOnCompletionListener(null);
mediaPlayer.setOnPreparedListener(null);
mediaPlayer.setOnErrorListener(null);
} catch (Exception e) {
Log.i(TAG, "IjkRelease: close listener error:" + e.getMessage());
}
try {
mediaPlayer.release();
} catch (Exception e) {
Log.i(TAG, "IjkRelease: release error:" + e.getMessage());
}
mediaPlayer = null;
Log.i(TAG, "IjkRelease: handle ok");
}
}
private void timeTriggerVideoPlay(final long fireTime, String ip) {
long delay = fireTime - System.currentTimeMillis();
if (delay <= 0) {
handler.postDelayed(NativePlayer.this::openMainDeviceAudio, open_audio_delay);
Log.i(TAG, "timeTriggerVideoPlay: Time later: fire time:" + fireTime);
return;
}
// 计算触发时间
handler.postDelayed(() -> {
long start = System.currentTimeMillis();
if (isCloseByUser) return;
try {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.seekTo(0);
handler.postDelayed(NativePlayer.this::openMainDeviceAudio, open_audio_delay);
Log.i(TAG, "timeTrigger: seek now: use time:" + (System.currentTimeMillis() - start));
} else {
Log.i(TAG, "timeTrigger: media condition no met");
}
} catch (Exception e) {
Log.i(TAG, "run: error:" + e.getMessage());
}
}, delay);
Log.i(TAG, "timeTriggerVideoPlay: fire time:" + fireTime + "; ip:" + ip + "; current time:"
+ System.currentTimeMillis() + "; user close:" + isCloseByUser + "; delay:" + delay);
}
private void openMainDeviceAudio() {
if (!MUtils.isMainDevice || audioManager == null || isCloseByUser) return;
try {
// ijk player
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.setVolume(1f, 1f);
Log.i(TAG, "openMainDeviceAudio: set volume 1f");
}
} catch (Exception e) {
Log.i(TAG, "openMainDeviceAudio: set volume error:" + e.getMessage());
}
}
}
标签:Log,mediaplayer,private,final,mediaPlayer,TAG,使用,IjkRelease,正确
From: https://www.cnblogs.com/futureli/p/18405778