|
@@ -4,7 +4,6 @@ import android.media.MediaPlayer;
|
|
|
import android.util.AttributeSet;
|
|
|
import android.view.Surface;
|
|
|
import android.view.View;
|
|
|
-import android.widget.VideoView;
|
|
|
|
|
|
import androidx.annotation.NonNull;
|
|
|
import androidx.annotation.Nullable;
|
|
@@ -14,62 +13,72 @@ import com.haochuan.core.IVideoPlayer;
|
|
|
import com.haochuan.core.Logger;
|
|
|
import com.haochuan.core.util.MediaStatusCode;
|
|
|
|
|
|
+import java.io.IOException;
|
|
|
+
|
|
|
+import tv.danmaku.ijk.media.player.IMediaPlayer;
|
|
|
+import tv.danmaku.ijk.media.player.IjkMediaPlayer;
|
|
|
+
|
|
|
import static com.haochuan.core.util.MessageCode.EXCEPTION_ERROR;
|
|
|
import static com.haochuan.core.util.MessageCode.PLAYER_OBJ_NULL;
|
|
|
|
|
|
-public class SystemVideoPlayer extends BaseMediaPlayer {
|
|
|
+public class IjkVideoPlayer extends BaseMediaPlayer {
|
|
|
|
|
|
//全局参数
|
|
|
- private VideoView videoView; //系统播放器对象
|
|
|
private IVideoPlayer iVideoPlayer; //播放器事件监控
|
|
|
- private MediaPlayer mediaPlayer;
|
|
|
+ private IMediaPlayer mediaPlayer;
|
|
|
private int playerStatus = MediaStatusCode.STOP;
|
|
|
protected boolean mHadPrepared = false; //Prepared
|
|
|
private int startTime = 0;//播放器开始的时间,单位毫秒
|
|
|
|
|
|
- //添加surface参数,以便替换vr模块传递过来的surface
|
|
|
- private Surface surface;
|
|
|
|
|
|
- public SystemVideoPlayer(@NonNull Context context) {
|
|
|
+ //ijk player播放器全局参数
|
|
|
+
|
|
|
+ public IjkVideoPlayer(@NonNull Context context) {
|
|
|
super(context);
|
|
|
init(context);
|
|
|
}
|
|
|
|
|
|
- public SystemVideoPlayer(@NonNull Context context, @Nullable AttributeSet attrs) {
|
|
|
+ public IjkVideoPlayer(@NonNull Context context, @Nullable AttributeSet attrs) {
|
|
|
super(context, attrs);
|
|
|
init(context);
|
|
|
}
|
|
|
|
|
|
- public SystemVideoPlayer(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
|
|
+ public IjkVideoPlayer(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
|
|
super(context, attrs, defStyleAttr);
|
|
|
init(context);
|
|
|
}
|
|
|
|
|
|
private void init(Context context){
|
|
|
Logger.d("SystemVideoPlayer,init()");
|
|
|
- View videoGroup = View.inflate(getContext(), R.layout.layout_system_video, this);
|
|
|
- videoView = videoGroup.findViewById(R.id.sys_video);
|
|
|
+ mediaPlayer = new IjkMediaPlayer();
|
|
|
initVideoView();
|
|
|
- videoView.resume();
|
|
|
+ enableHardwareDecoding();
|
|
|
+ }
|
|
|
+
|
|
|
+ /*开启硬件加速*/
|
|
|
+ private void enableHardwareDecoding(){
|
|
|
+ if (mediaPlayer instanceof IjkMediaPlayer){
|
|
|
+ IjkMediaPlayer player = (IjkMediaPlayer) mediaPlayer;
|
|
|
+ player.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1);
|
|
|
+ player.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-auto-rotate", 1);
|
|
|
+ player.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "overlay-format", IjkMediaPlayer.SDL_FCC_RV32);
|
|
|
+ player.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 60);
|
|
|
+ player.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max-fps", 0);
|
|
|
+ player.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "skip_loop_filter", 48);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private void initVideoView(){
|
|
|
Logger.d("SystemVideoPlayer,initVideoView()");
|
|
|
- videoView.setOnPreparedListener((mp) ->{
|
|
|
- mediaPlayer = mp;
|
|
|
- if(this.surface != null){
|
|
|
- mediaPlayer.setSurface(this.surface);
|
|
|
- }else{
|
|
|
- Logger.d("vr surface is null");
|
|
|
- }
|
|
|
+ mediaPlayer.setOnPreparedListener((mp) ->{
|
|
|
+ mediaPlayer.start();
|
|
|
iVideoPlayer.onPlaying();
|
|
|
playerStatus = MediaStatusCode.PLAY;
|
|
|
mHadPrepared = true;
|
|
|
seekToStartTime();
|
|
|
});
|
|
|
|
|
|
- videoView.setOnInfoListener((mp,what,extra) -> {
|
|
|
- mediaPlayer = mp;
|
|
|
+ mediaPlayer.setOnInfoListener((mp,what,extra) -> {
|
|
|
switch (what){ //信息类型
|
|
|
case MediaPlayer.MEDIA_INFO_BUFFERING_START:
|
|
|
// MediaPlayer暂时暂停内部播放以缓冲更多数据。
|
|
@@ -87,16 +96,14 @@ public class SystemVideoPlayer extends BaseMediaPlayer {
|
|
|
return true;
|
|
|
});
|
|
|
|
|
|
- videoView.setOnErrorListener((mp,what,extra) -> {
|
|
|
- mediaPlayer = mp;
|
|
|
+ mediaPlayer.setOnErrorListener((mp,what,extra) -> {
|
|
|
iVideoPlayer.onError(what,extra);
|
|
|
playerStatus = MediaStatusCode.STOP;
|
|
|
mHadPrepared = false;
|
|
|
return true;
|
|
|
});
|
|
|
|
|
|
- videoView.setOnCompletionListener((mp) ->{
|
|
|
- mediaPlayer = mp;
|
|
|
+ mediaPlayer.setOnCompletionListener((mp) ->{
|
|
|
iVideoPlayer.onCompletion();
|
|
|
mHadPrepared = false;
|
|
|
playerStatus = MediaStatusCode.COMPLETE;
|
|
@@ -107,15 +114,19 @@ public class SystemVideoPlayer extends BaseMediaPlayer {
|
|
|
|
|
|
@Override
|
|
|
public void play(String url, String examineId, String examineType) {
|
|
|
- Logger.d(String.format("SystemVideoPlayer,play(%s,%s,%s)",
|
|
|
- url,examineId,examineType));
|
|
|
- if (videoView == null) {
|
|
|
- Logger.e(PLAYER_OBJ_NULL,"播放器对象为null,退出执行");
|
|
|
- return;
|
|
|
+ try {
|
|
|
+ Logger.d(String.format("SystemVideoPlayer,play(%s,%s,%s)",
|
|
|
+ url,examineId,examineType));
|
|
|
+ if (mediaPlayer == null) {
|
|
|
+ Logger.e(PLAYER_OBJ_NULL,"播放器对象为null,退出执行");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ mediaPlayer.setDataSource(url);
|
|
|
+ mediaPlayer.prepareAsync();
|
|
|
+ playerStatus = MediaStatusCode.PREPARE; //视频准备中;
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
}
|
|
|
- videoView.setVideoPath(url);
|
|
|
- videoView.start();
|
|
|
- playerStatus = MediaStatusCode.PREPARE; //视频准备中;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -128,12 +139,12 @@ public class SystemVideoPlayer extends BaseMediaPlayer {
|
|
|
@Override
|
|
|
public void resume() {
|
|
|
Logger.d("SystemVideoPlayer,resume()");
|
|
|
- if (videoView == null) {
|
|
|
+ if (mediaPlayer == null) {
|
|
|
Logger.e(PLAYER_OBJ_NULL,"播放器对象为null,退出执行");
|
|
|
return;
|
|
|
}
|
|
|
if(isPrePared()){
|
|
|
- videoView.start();
|
|
|
+ mediaPlayer.start();
|
|
|
playerStatus = MediaStatusCode.PLAY; //播放中;
|
|
|
iVideoPlayer.onResume();
|
|
|
}else{
|
|
@@ -144,12 +155,12 @@ public class SystemVideoPlayer extends BaseMediaPlayer {
|
|
|
@Override
|
|
|
public void pause() {
|
|
|
Logger.d("SystemVideoPlayer,pause()");
|
|
|
- if (videoView == null) {
|
|
|
+ if (mediaPlayer == null) {
|
|
|
Logger.e(PLAYER_OBJ_NULL,"播放器对象为null,退出执行");
|
|
|
return;
|
|
|
}
|
|
|
if(isPrePared()){
|
|
|
- videoView.pause();
|
|
|
+ mediaPlayer.pause();
|
|
|
playerStatus = MediaStatusCode.PAUSE; //暂停中;
|
|
|
iVideoPlayer.onPause();
|
|
|
}else{
|
|
@@ -161,12 +172,12 @@ public class SystemVideoPlayer extends BaseMediaPlayer {
|
|
|
public void seek(int position) {
|
|
|
Logger.d(String.format("SystemVideoPlayer,seek(%s)",
|
|
|
position));
|
|
|
- if (videoView == null) {
|
|
|
+ if (mediaPlayer == null) {
|
|
|
Logger.e(PLAYER_OBJ_NULL,"播放器对象为null,退出执行");
|
|
|
return;
|
|
|
}
|
|
|
if(isPrePared()){
|
|
|
- videoView.seekTo(position);
|
|
|
+ mediaPlayer.seekTo(position);
|
|
|
}else{
|
|
|
Logger.w("视频未准备好,不能seek");
|
|
|
}
|
|
@@ -175,12 +186,11 @@ public class SystemVideoPlayer extends BaseMediaPlayer {
|
|
|
@Override
|
|
|
public void release() {
|
|
|
Logger.d("SystemVideoPlayer,release()");
|
|
|
- if (videoView == null) {
|
|
|
+ if (mediaPlayer == null) {
|
|
|
Logger.e(PLAYER_OBJ_NULL,"播放器对象为null,退出执行");
|
|
|
return;
|
|
|
}
|
|
|
- videoView.stopPlayback();
|
|
|
- videoView.suspend();
|
|
|
+ mediaPlayer.release();
|
|
|
mHadPrepared = false;
|
|
|
playerStatus = MediaStatusCode.STOP; //暂停中;
|
|
|
iVideoPlayer.onDestroy();
|
|
@@ -211,7 +221,7 @@ public class SystemVideoPlayer extends BaseMediaPlayer {
|
|
|
}
|
|
|
if (isPrePared()) {
|
|
|
//如果视频未准备好,获取时长会报错,导致无法正常播放
|
|
|
- return mediaPlayer.getDuration();
|
|
|
+ return (int)mediaPlayer.getDuration();
|
|
|
}
|
|
|
return EXCEPTION_ERROR;
|
|
|
}
|
|
@@ -223,7 +233,7 @@ public class SystemVideoPlayer extends BaseMediaPlayer {
|
|
|
Logger.e(PLAYER_OBJ_NULL,"播放器对象为null,退出执行");
|
|
|
return 0;
|
|
|
}
|
|
|
- return mediaPlayer.getCurrentPosition();
|
|
|
+ return (int)mediaPlayer.getCurrentPosition();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -240,7 +250,7 @@ public class SystemVideoPlayer extends BaseMediaPlayer {
|
|
|
|
|
|
@Override
|
|
|
public void setSurface(@NonNull Surface surface) {
|
|
|
- this.surface = surface;
|
|
|
+ mediaPlayer.setSurface(surface);
|
|
|
}
|
|
|
|
|
|
/*----------------------功能函数-----------------------------*/
|
|
@@ -249,16 +259,16 @@ public class SystemVideoPlayer extends BaseMediaPlayer {
|
|
|
* */
|
|
|
private void seekToStartTime(){
|
|
|
Logger.d("SystemVideoPlayer,seekToStartTime()");
|
|
|
- if(videoView == null){
|
|
|
+ if(mediaPlayer == null){
|
|
|
Logger.e(PLAYER_OBJ_NULL,"videoView is null, can`t seekToStartTime");
|
|
|
return;
|
|
|
}
|
|
|
if(startTime > 0){
|
|
|
if(startTime >= getDuration()){
|
|
|
//如果开始时间大于或者等于视频总时长,则跳转到距离结束5秒的位置
|
|
|
- videoView.seekTo(getDuration() -5000);
|
|
|
+ mediaPlayer.seekTo(getDuration() -5000);
|
|
|
}else{
|
|
|
- videoView.seekTo(startTime);
|
|
|
+ mediaPlayer.seekTo(startTime);
|
|
|
}
|
|
|
}
|
|
|
}
|