package com.xixun.xixunplayer; import android.content.Context; import android.graphics.Bitmap; 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 EleVideo extends TextureView implements TextureView.SurfaceTextureListener { String path; float vol; IjkMediaPlayer ijkPlayer; ExoPlayer exoPlayer; long bitRate; boolean isLive; public EleVideo(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(); } }