Android/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/SrcVideo.java
2024-02-02 21:51:16 +08:00

137 lines
4.5 KiB
Java

package com.xixun.xixunplayer;
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.view.Surface;
import android.view.TextureView;
import androidx.annotation.NonNull;
import androidx.annotation.OptIn;
import androidx.media3.common.MediaItem;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.SeekParameters;
import tv.danmaku.ijk.media.player.IMediaPlayer;
import tv.danmaku.ijk.media.player.IjkMediaPlayer;
public class SrcVideo extends TextureView implements TextureView.SurfaceTextureListener {
String path;
float vol;
IjkMediaPlayer ijkPlayer;
ExoPlayer exoPlayer;
long bitRate;
boolean isLive;
public SrcVideo(Context context, String path, float vol, boolean isLive) {
super(context);
this.path = path;
this.vol = vol;
this.isLive = isLive;
initIjk();
}
@OptIn(markerClass = UnstableApi.class)
void initExo() {
exoPlayer = new ExoPlayer.Builder(getContext()).build();
exoPlayer.setMediaItem(MediaItem.fromUri(path));
exoPlayer.setRepeatMode(ExoPlayer.REPEAT_MODE_ONE);
exoPlayer.setSeekParameters(SeekParameters.CLOSEST_SYNC);
exoPlayer.setVolume(vol);
exoPlayer.setVideoTextureView(this);
exoPlayer.prepare();
}
void initIjk() {
ijkPlayer = new IjkMediaPlayer();
//ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1);
ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 0);
ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzeduration", 1);
ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "skip_loop_filter", 48);
try {
setSurfaceTextureListener(this);
ijkPlayer.setDataSource(path);
ijkPlayer.setLooping(true);
ijkPlayer.setVolume(vol, vol);
ijkPlayer.setOnPreparedListener((IMediaPlayer var1)->{
bitRate = ijkPlayer.getBitRate();
if(bitRate > 12000000) {
setSurfaceTextureListener(null);
release();
initExo();
}
if(isShown() || isLive) start();
});
ijkPlayer.prepareAsync();
} catch (Throwable e) {
Util.makeText(getContext(), Util.toStr(e)).show();
Util.printStackTrace(e);
ijkPlayer = null;
}
}
@Override
public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surface, int width, int height) {
if(ijkPlayer!=null) ijkPlayer.setSurface(new Surface(surface));
}
@Override
public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width, int height) {
}
@Override
public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) {
return false;
}
@Override
public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {
}
void start() {
if(ijkPlayer!=null) {
ijkPlayer.seekTo(0);
ijkPlayer.start();
} else if(exoPlayer!=null) {
if(exoPlayer.getPlaybackState()==ExoPlayer.STATE_IDLE) exoPlayer.prepare();
exoPlayer.play();
}
}
void pause() {
if(ijkPlayer!=null) {
ijkPlayer.pause();
ijkPlayer.seekTo(0);
}
if(exoPlayer!=null && exoPlayer.isPlaying()) {
exoPlayer.pause();
exoPlayer.seekToDefaultPosition();
}
}
void release() {
if(ijkPlayer!=null) {
ijkPlayer.release();
ijkPlayer = null;
}
if(exoPlayer!=null) {
exoPlayer.release();
exoPlayer = null;
}
}
String getState() {
if(exoPlayer!=null) {
var state = exoPlayer.getPlaybackState();
if(state==ExoPlayer.STATE_IDLE) return "STATE_IDLE";
if(state==ExoPlayer.STATE_BUFFERING) return "STATE_BUFFERING";
if(state==ExoPlayer.STATE_READY) return "STATE_READY";
if(state==ExoPlayer.STATE_ENDED) return "STATE_ENDED";
}
return "null";
}
@Override
public void onVisibilityAggregated(boolean isVisible) {
super.onVisibilityAggregated(isVisible);
if(isVisible) {
start();
if(isLive) ijkPlayer.setVolume(vol, vol);
} else if(isLive) ijkPlayer.setVolume(0, 0);
else pause();
}
}