CarGuo / GSYVideoPlayer

视频播放器(IJKplayer、ExoPlayer、MediaPlayer),HTTPS,16k page size,支持弹幕,外挂字幕,支持滤镜、水印、gif截图,片头广告、中间广告,多个同时播放,支持基本的拖动,声音、亮度调节,支持边播边缓存,支持视频自带rotation的旋转(90,270之类),重力旋转与手动旋转的同步支持,支持列表播放 ,列表全屏动画,视频加载速度,列表小窗口支持拖动,动画效果,调整比例,多分辨率切换,支持切换播放器,进度条小窗口预览,列表切换详情页面无缝播放,rtsp、concat、mpeg。
https://juejin.cn/user/817692379985752/posts
Apache License 2.0
20.21k stars 4.19k forks source link

提问:关于自定义内核 #2114

Closed spysoos closed 5 years ago

spysoos commented 5 years ago

(!!!!请务必务必按照issue模板,修改 后提交问题!!!!,不按模板提Isuue删除处理)

(ps 首页问题集锦和demo请先了解一下!)

问题描述:

请问这个库能把内核切换成腾讯云的超级播放器吗? 腾讯的播放器本身他也是基于ijk的,但是项目需要,只能用它的播放器,所以想知道如果要切换到它的内核,需要做哪些工作,谢谢

问题机型/系统:

例如 真机 小米note2 Android7.0

GSY依赖版本

implementation 'com.shuyu:gsyVideoPlayer-java:7.0.1'

Demo中的复现步骤

Demo中的detailPlayer页面打开后XXXX会出现这个问题。

问题代码:(如果有)

xxxxxxx

问题log(如果有)


xxxxxxx
CarGuo commented 5 years ago

首先,你只依赖 java 文件,然后 自定义 playerManager ,具体可以参考类似 https://github.com/CarGuo/GSYVideoPlayer/tree/master/app/src/main/java/com/example/gsyvideoplayer/exo

spysoos commented 5 years ago

@CarGuo 具体我是不是只要实现以下这三个类就好了? TIM截图20190704101448

CarGuo commented 5 years ago

嗯嗯,然后把 playermanager 装在进去

xwlcn commented 3 years ago

我也打算换内核了。。Ijk内核真的不太好用,我用的时候主要有两个问题:1.视频开始时经常要加载很久才出来 2.m3u8经常播着播着就停了无法继续播放 这两个问题exo就不会,但exo貌似支持的音视频格式很少。 打算换成迅雷的APlayer或者金山的KSPlayer试试了。

henryneu commented 3 years ago

腾讯的超级播放器,我没找到好的引入方式,超级播放器自己把ijk包了一层,对外暴露的player不是依赖于 IMediaPlayer,而如果我们继承自 AbstractMediaPlayer 把 mInternalPlayer 设置为 腾讯的播放器,很多地方都没法儿设置,比如start,stop等是直接设置给 mInternalPlayer 的,但是腾讯暴露出来的播放器是没有这些对应方法,你是怎么换成功的?

kxbyte commented 2 years ago

腾讯的超级播放器,我没找到好的引入方式,超级播放器自己把ijk包了一层,对外暴露的player不是依赖于 IMediaPlayer,而如果我们继承自 AbstractMediaPlayer 把 mInternalPlayer 设置为 腾讯的播放器,很多地方都没法儿设置,比如start,stop等是直接设置给 mInternalPlayer 的,但是腾讯暴露出来的播放器是没有这些对应方法,你是怎么换成功的?

换成功了吗,求一份代码

henryneu commented 2 years ago

腾讯的超级播放器,我没找到好的引入方式,超级播放器自己把ijk包了一层,对外暴露的player不是依赖于 IMediaPlayer,而如果我们继承自 AbstractMediaPlayer 把 mInternalPlayer 设置为 腾讯的播放器,很多地方都没法儿设置,比如start,stop等是直接设置给 mInternalPlayer 的,但是腾讯暴露出来的播放器是没有这些对应方法,你是怎么换成功的?

换成功了吗,求一份代码

没有成功,不过可以给你看看代码,大家都可以试试

TencentSuperPlayer.java

import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Surface;
import android.view.SurfaceHolder;

import com.tencent.rtmp.ITXVodPlayListener;
import com.tencent.rtmp.TXLiveConstants;
import com.tencent.rtmp.TXVodPlayConfig;
import com.tencent.rtmp.TXVodPlayer;

import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
import java.util.Map;

import tv.danmaku.ijk.media.player.AbstractMediaPlayer;
import tv.danmaku.ijk.media.player.MediaInfo;
import tv.danmaku.ijk.media.player.misc.IMediaDataSource;
import tv.danmaku.ijk.media.player.misc.ITrackInfo;

/**
 * @Version: 1.0.0
 * @Description: TencentSuperPlayer
 */
public class TencentSuperPlayer extends AbstractMediaPlayer {
    private TXVodPlayer txVodPlayer;
    private MediaInfo mediaInfo;
    private boolean mIsReleased;
    private boolean isPause;
    private String url;
    private Surface surface;
    private boolean canStart;
    private long progress_ms;//播放进度
    private long duration_ms_total;//视频总长
    private Context mContext;

    public TencentSuperPlayer(Context context) {
        this.mContext = context;
        txVodPlayer = new TXVodPlayer(context);
        txVodPlayer.getCurrentPlaybackTime();
        SuperPlayerGlobalConfig config = SuperPlayerGlobalConfig.getInstance();
        TXVodPlayConfig mVodPlayConfig = new TXVodPlayConfig();

        File sdcardDir = context.getExternalFilesDir(null);
        if (sdcardDir != null) {
            mVodPlayConfig.setCacheFolderPath(sdcardDir.getPath() + "/txcache");
        }
        mVodPlayConfig.setMaxCacheItems(config.maxCacheItem);
        txVodPlayer.setConfig(mVodPlayConfig);
        txVodPlayer.setRenderMode(config.renderMode);
        txVodPlayer.enableHardwareDecode(config.enableHWAcceleration);
        txVodPlayer.setVodListener(new ITXVodPlayListener() {
            @Override
            public void onPlayEvent(TXVodPlayer txVodPlayer, int event, Bundle param) {
                if (BuildConfig.DEBUG) LogUtils.i("--TencentSuperPlayer--", "--event--" + event);
                if (event == TXLiveConstants.PLAY_EVT_PLAY_BEGIN) {//视频播放开始
                    //notifyOnPrepared();
                    if (BuildConfig.DEBUG) LogUtils.i("--TencentSuperPlayer--", "视频播放开始");
                } else if (event == TXLiveConstants.PLAY_EVT_VOD_LOADING_END) {//loadingEnd
                    if (BuildConfig.DEBUG) LogUtils.i("--TencentSuperPlayer--", "loadingEnd");
                    // 没有这个事件,发一个广播出去
                    //LocalBroadcastManager.getInstance(mContext).sendBroadcast(new Intent(AppConstant.PLAY_EVT_VOD_LOADING_END));
                } else if (event == TXLiveConstants.PLAY_EVT_PLAY_PROGRESS) {//视频播放进度
                    // 加载进度, 单位是毫秒
                    int duration_ms = param.getInt(TXLiveConstants.EVT_PLAYABLE_DURATION_MS);
                    // 播放进度, 单位是毫秒
                    progress_ms = param.getInt(TXLiveConstants.EVT_PLAY_PROGRESS_MS);
                    // 视频总长, 单位是毫秒
                    duration_ms_total = param.getInt(TXLiveConstants.EVT_PLAY_DURATION_MS);
                    if (BuildConfig.DEBUG) {
                        LogUtils.i("--TencentSuperPlayer--", "播放进度:" + param.getInt(TXLiveConstants.EVT_PLAY_PROGRESS_MS));
                    }
                    //notifyOnBufferingUpdate(duration_ms);
                } else if (event == TXLiveConstants.PLAY_EVT_PLAY_END) {//视频播放结束
                    //notifyOnCompletion();
                    if (BuildConfig.DEBUG) LogUtils.i("--TencentSuperPlayer--", "视频播放结束");
                } else if (event == TXLiveConstants.PLAY_ERR_NET_DISCONNECT || event == TXLiveConstants.PLAY_WARNING_RECONNECT) {//网络断连
                    //notifyOnError(event, 1);
                    if (BuildConfig.DEBUG) LogUtils.i("--TencentSuperPlayer--", "网络断连");
                } else if (event == TXLiveConstants.PLAY_WARNING_VIDEO_DECODE_FAIL) {//当前视频帧解码失败
                    //notifyOnError(event, 1);
                    if (BuildConfig.DEBUG) LogUtils.i("--TencentSuperPlayer--", "当前视频帧解码失败");
                } else if (event == TXLiveConstants.PLAY_WARNING_AUDIO_DECODE_FAIL) {//当前音频帧解码失败
                    //notifyOnError(event, 1);
                    if (BuildConfig.DEBUG) LogUtils.i("--TencentSuperPlayer--", "当前音频帧解码失败");
                } else if (event == TXLiveConstants.PLAY_WARNING_HW_ACCELERATION_FAIL) {//硬解失败
                    if (BuildConfig.DEBUG) LogUtils.i("--TencentSuperPlayer--", "硬解失败");
                } else if (event == TXLiveConstants.PLAY_EVT_CHANGE_RESOLUTION) {//视频分辨率改变
                    //notifyOnVideoSizeChanged(param.getInt(TXLiveConstants.EVT_PARAM1), param.getInt(TXLiveConstants.EVT_PARAM2), getVideoSarNum(), getVideoSarNum());
                    if (BuildConfig.DEBUG) LogUtils.i("--TencentSuperPlayer--", "视频分辨率改变");
                }
            }

            @Override
            public void onNetStatus(TXVodPlayer txVodPlayer, Bundle bundle) {

            }
        });
    }

    @Override
    public void setDisplay(SurfaceHolder sh) {
        Surface surface = sh.getSurface();
        setSurface(surface);
    }

    @Override
    public void setDataSource(Context context, Uri uri) throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
        this.url = uri.getPath();
    }

    @Override
    public void setDataSource(Context context, Uri uri, Map<String, String> map) throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
        this.url = uri.toString();
    }

    @Override
    public void setDataSource(FileDescriptor fileDescriptor) throws IOException, IllegalArgumentException, IllegalStateException {
    }

    @Override
    public void setDataSource(String url) throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
        this.url = url;
    }

    @Override
    public String getDataSource() {
        return url;
    }

    @Override
    public void prepareAsync() throws IllegalStateException {
        //notifyOnPrepared();
    }

    @Override
    public void start() throws IllegalStateException {
        if (isPause) {
            // 暂停后恢复播放
            isPause = false;
            txVodPlayer.resume();
        } else {
            if (TextUtils.isEmpty(url) || surface == null) {
                canStart = true;
                return;
            }
            this.txVodPlayer.startPlay(url);
        }
    }

    @Override
    public void stop() throws IllegalStateException {
        isPause = false;
        this.txVodPlayer.stopPlay(false);
    }

    @Override
    public void pause() throws IllegalStateException {
        isPause = true;
        this.txVodPlayer.pause();
    }

    @Override
    public void setScreenOnWhilePlaying(boolean screenOn) {
        //txVodPlayer.setScreenOnWhilePlaying(screenOn);
    }

    @Override
    public int getVideoWidth() {
        return txVodPlayer.getWidth();
    }

    @Override
    public int getVideoHeight() {
        return txVodPlayer.getHeight();
    }

    @Override
    public boolean isPlaying() {
        return txVodPlayer.isPlaying();
    }

    @Override
    public void seekTo(long msec) throws IllegalStateException {
        float v = msec / 1000.0f;
        this.txVodPlayer.seek(v);//腾讯这儿是百分比
    }

    @Override
    public long getCurrentPosition() {
        return progress_ms;
        //return (long) txVodPlayer.getCurrentPlaybackTime();
    }

    @Override
    public long getDuration() {
        return duration_ms_total;
        //float duration = txVodPlayer.getDuration();
        //return (long) duration;
    }

    @Override
    public void release() {
        txVodPlayer.stopPlay(true);
        this.mIsReleased = true;
        this.resetListeners();
    }

    @Override
    public void reset() {
        //txVodPlayer.resume();//这个是恢复播放的
        this.resetListeners();
    }

    @Override
    public void setVolume(float leftVolume, float rightVolume) {
        txVodPlayer.setMute(leftVolume + rightVolume == 0);
    }

    @Override
    public int getAudioSessionId() {
        return 0;
    }

    @Override
    public MediaInfo getMediaInfo() {
        if (mediaInfo == null) {
            MediaInfo module = new MediaInfo();
            module.mVideoDecoder = "TencentSuperPlayer";
            module.mVideoDecoderImpl = "HW";
            module.mAudioDecoder = "TencentSuperPlayer";
            module.mAudioDecoderImpl = "HW";
            mediaInfo = module;
        }
        return mediaInfo;
    }

    @Override
    public void setLogEnabled(boolean b) {
    }

    @Override
    public boolean isPlayable() {
        return true;
    }

    @Override
    public void setAudioStreamType(int streamtype) {
    }

    @Override
    public void setKeepInBackground(boolean keepInBackground) {

    }

    @Override
    public int getVideoSarNum() {
        return 1;
    }

    @Override
    public int getVideoSarDen() {
        return 1;
    }

    @Override
    public void setWakeMode(Context context, int mode) {
    }

    @Override
    public void setLooping(boolean b) {
        txVodPlayer.setLoop(b);
    }

    @Override
    public boolean isLooping() {
        return txVodPlayer.isLoop();
    }

    @Override
    public ITrackInfo[] getTrackInfo() {
        return new ITrackInfo[0];
    }

    @Override
    public void setSurface(Surface surface) {
        if (surface == this.surface) return;
        this.surface = surface;
        /*if (surface == null) {
            if (!isPause) pause();
        }*/
        txVodPlayer.setSurface(surface);
        if (surface == null) return;
        if (TextUtils.isEmpty(url)) return;
        if (canStart) {
            canStart = false;
            start();
        /*} else if (isPause) {
            start();*/
        }
    }

    @Override
    public void setDataSource(IMediaDataSource iMediaDataSource) {

    }

    public TXVodPlayer getMediaPlayer() {
        return txVodPlayer;
    }
}
TencentSuperPlayerManager.java
import android.content.Context;
import android.media.AudioManager;
import android.os.Message;
import android.view.Surface;

import java.util.List;

import tv.danmaku.ijk.media.player.IMediaPlayer;

/**
 * date   : 2021/10/14 8:21 下午
 * desc   : 腾讯超级视频播放器管理器
 * version: 1.0.0
 */
public class TencentSuperPlayerManager extends BasePlayerManager {
    private TencentSuperPlayer mediaPlayer;
    //private boolean release;
    private Surface surface;

    @Override
    public IMediaPlayer getMediaPlayer() {
        return mediaPlayer;
    }

    @Override
    public void initVideoPlayer(Context context, Message message, List<VideoOptionModel> optionModelList, ICacheManager cacheManager) {
        mediaPlayer = new TencentSuperPlayer(context);
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        //release = false;
        VideoModel videoModel = (VideoModel) message.obj;
        try {
            if (videoModel.isCache() && cacheManager != null) {
                cacheManager.doCacheLogic(context, mediaPlayer, videoModel.getUrl(), videoModel.getMapHeadData(), videoModel.getCachePath());
            } else {
                mediaPlayer.setDataSource(videoModel.getUrl());
            }
            mediaPlayer.setLooping(videoModel.isLooping());
            if (videoModel.getSpeed() != 1 && videoModel.getSpeed() > 0) {
                setSpeed(videoModel.getSpeed());
            }
        } catch (Exception e) {
            if (BuildConfig.DEBUG) e.printStackTrace();
        }
        // 播放内核初始化成功
        initSuccess(videoModel);
    }

    @Override
    public void showDisplay(Message msg) {
        /*Surface holder = (Surface) msg.obj;
        if (holder == null && mediaPlayer != null && !release) {
            mediaPlayer.setSurface(null);
        } else if (holder != null) {
            if (mediaPlayer != null && holder.isValid() && !release) {
                mediaPlayer.setSurface(holder);
            }
            // if (surface != null) surface.release();
            surface = holder;
        }*/
        if (msg.obj == null && mediaPlayer != null) {
            mediaPlayer.setSurface(null);
        } else {
            Surface holder = (Surface) msg.obj;
            surface = holder;
            if (mediaPlayer != null && holder.isValid()) {
                mediaPlayer.setSurface(holder);
            }
        }
    }

    @Override
    public void setNeedMute(boolean needMute) {
        // 是否静音
        /*if (mediaPlayer != null && !release) {
            if (needMute) {
                mediaPlayer.setVolume(0, 0);
            } else mediaPlayer.setVolume(1, 1);
        }*/
        if (mediaPlayer != null) {
            if (needMute) {
                mediaPlayer.setVolume(0, 0);
            } else mediaPlayer.setVolume(1, 1);
        }
    }

    @Override
    public void setVolume(float left, float right) {

    }

    @Override
    public void releaseSurface() {
        if (surface != null) {
            //surface.release();
            surface = null;
        }
    }

    @Override
    public void release() {
        if (mediaPlayer != null) {
            //release = true;
            mediaPlayer.release();
        }
    }

    @Override
    public int getBufferedPercentage() {
        if (mediaPlayer == null) return -1;
        else return (int) mediaPlayer.getMediaPlayer().getBufferDuration();
    }

    @Override
    public long getNetSpeed() {
        //if (mediaPlayer == null)
        return 0;
    }

    @Override
    public void setSpeedPlaying(float speed, boolean soundTouch) {

    }

    @Override
    public boolean isSurfaceSupportLockCanvas() {
        return false;
    }

    @Override
    public void setSpeed(float speed, boolean soundTouch) {
        setSpeed(speed);
    }

    private void setSpeed(float speed) {
        /*if (release) {
            return;
        }*/
        if (mediaPlayer != null && mediaPlayer.getMediaPlayer() != null && mediaPlayer.isPlayable()) {
            mediaPlayer.getMediaPlayer().setRate(speed);
        }
    }

    @Override
    public void start() {
        if (mediaPlayer != null) mediaPlayer.start();
    }

    @Override
    public void stop() {
        if (mediaPlayer != null) mediaPlayer.stop();
    }

    @Override
    public void pause() {
        if (mediaPlayer != null) mediaPlayer.pause();
    }

    @Override
    public int getVideoWidth() {
        if (mediaPlayer == null) return 0;
        else return mediaPlayer.getVideoWidth();
    }

    @Override
    public int getVideoHeight() {
        if (mediaPlayer == null) return 0;
        else return mediaPlayer.getVideoHeight();
    }

    @Override
    public boolean isPlaying() {
        if (mediaPlayer == null) return false;
        else return mediaPlayer.isPlaying();
    }

    @Override
    public void seekTo(long time) {
        if (mediaPlayer == null) return;
        else mediaPlayer.seekTo(time);
    }

    @Override
    public long getCurrentPosition() {
        if (mediaPlayer == null) return 0;
        else return mediaPlayer.getCurrentPosition();
    }

    @Override
    public long getDuration() {
        if (mediaPlayer == null) return 0;
        else return mediaPlayer.getDuration();
    }

    @Override
    public int getVideoSarNum() {
        if (mediaPlayer == null) return 0;
        else return mediaPlayer.getVideoSarNum();
    }

    @Override
    public int getVideoSarDen() {
        if (mediaPlayer == null) return 0;
        else return mediaPlayer.getVideoSarDen();
    }
}
chuanye1993 commented 1 month ago

腾讯的超级播放器,我没找到好的引入方式,超级播放器自己把ijk包了一层,对外暴露的player不是依赖于 IMediaPlayer,而如果我们继承自 AbstractMediaPlayer 把 mInternalPlayer 设置为 腾讯的播放器,很多地方都没法儿设置,比如start,stop等是直接设置给 mInternalPlayer 的,但是腾讯暴露出来的播放器是没有这些对应方法,你是怎么换成功的?

换成功了吗,求一份代码

没有成功,不过可以给你看看代码,大家都可以试试

TencentSuperPlayer.java

import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Surface;
import android.view.SurfaceHolder;

import com.tencent.rtmp.ITXVodPlayListener;
import com.tencent.rtmp.TXLiveConstants;
import com.tencent.rtmp.TXVodPlayConfig;
import com.tencent.rtmp.TXVodPlayer;

import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
import java.util.Map;

import tv.danmaku.ijk.media.player.AbstractMediaPlayer;
import tv.danmaku.ijk.media.player.MediaInfo;
import tv.danmaku.ijk.media.player.misc.IMediaDataSource;
import tv.danmaku.ijk.media.player.misc.ITrackInfo;

/**
 * @Version: 1.0.0
 * @Description: TencentSuperPlayer
 */
public class TencentSuperPlayer extends AbstractMediaPlayer {
    private TXVodPlayer txVodPlayer;
    private MediaInfo mediaInfo;
    private boolean mIsReleased;
    private boolean isPause;
    private String url;
    private Surface surface;
    private boolean canStart;
    private long progress_ms;//播放进度
    private long duration_ms_total;//视频总长
    private Context mContext;

    public TencentSuperPlayer(Context context) {
        this.mContext = context;
        txVodPlayer = new TXVodPlayer(context);
        txVodPlayer.getCurrentPlaybackTime();
        SuperPlayerGlobalConfig config = SuperPlayerGlobalConfig.getInstance();
        TXVodPlayConfig mVodPlayConfig = new TXVodPlayConfig();

        File sdcardDir = context.getExternalFilesDir(null);
        if (sdcardDir != null) {
            mVodPlayConfig.setCacheFolderPath(sdcardDir.getPath() + "/txcache");
        }
        mVodPlayConfig.setMaxCacheItems(config.maxCacheItem);
        txVodPlayer.setConfig(mVodPlayConfig);
        txVodPlayer.setRenderMode(config.renderMode);
        txVodPlayer.enableHardwareDecode(config.enableHWAcceleration);
        txVodPlayer.setVodListener(new ITXVodPlayListener() {
            @Override
            public void onPlayEvent(TXVodPlayer txVodPlayer, int event, Bundle param) {
                if (BuildConfig.DEBUG) LogUtils.i("--TencentSuperPlayer--", "--event--" + event);
                if (event == TXLiveConstants.PLAY_EVT_PLAY_BEGIN) {//视频播放开始
                    //notifyOnPrepared();
                    if (BuildConfig.DEBUG) LogUtils.i("--TencentSuperPlayer--", "视频播放开始");
                } else if (event == TXLiveConstants.PLAY_EVT_VOD_LOADING_END) {//loadingEnd
                    if (BuildConfig.DEBUG) LogUtils.i("--TencentSuperPlayer--", "loadingEnd");
                    // 没有这个事件,发一个广播出去
                    //LocalBroadcastManager.getInstance(mContext).sendBroadcast(new Intent(AppConstant.PLAY_EVT_VOD_LOADING_END));
                } else if (event == TXLiveConstants.PLAY_EVT_PLAY_PROGRESS) {//视频播放进度
                    // 加载进度, 单位是毫秒
                    int duration_ms = param.getInt(TXLiveConstants.EVT_PLAYABLE_DURATION_MS);
                    // 播放进度, 单位是毫秒
                    progress_ms = param.getInt(TXLiveConstants.EVT_PLAY_PROGRESS_MS);
                    // 视频总长, 单位是毫秒
                    duration_ms_total = param.getInt(TXLiveConstants.EVT_PLAY_DURATION_MS);
                    if (BuildConfig.DEBUG) {
                        LogUtils.i("--TencentSuperPlayer--", "播放进度:" + param.getInt(TXLiveConstants.EVT_PLAY_PROGRESS_MS));
                    }
                    //notifyOnBufferingUpdate(duration_ms);
                } else if (event == TXLiveConstants.PLAY_EVT_PLAY_END) {//视频播放结束
                    //notifyOnCompletion();
                    if (BuildConfig.DEBUG) LogUtils.i("--TencentSuperPlayer--", "视频播放结束");
                } else if (event == TXLiveConstants.PLAY_ERR_NET_DISCONNECT || event == TXLiveConstants.PLAY_WARNING_RECONNECT) {//网络断连
                    //notifyOnError(event, 1);
                    if (BuildConfig.DEBUG) LogUtils.i("--TencentSuperPlayer--", "网络断连");
                } else if (event == TXLiveConstants.PLAY_WARNING_VIDEO_DECODE_FAIL) {//当前视频帧解码失败
                    //notifyOnError(event, 1);
                    if (BuildConfig.DEBUG) LogUtils.i("--TencentSuperPlayer--", "当前视频帧解码失败");
                } else if (event == TXLiveConstants.PLAY_WARNING_AUDIO_DECODE_FAIL) {//当前音频帧解码失败
                    //notifyOnError(event, 1);
                    if (BuildConfig.DEBUG) LogUtils.i("--TencentSuperPlayer--", "当前音频帧解码失败");
                } else if (event == TXLiveConstants.PLAY_WARNING_HW_ACCELERATION_FAIL) {//硬解失败
                    if (BuildConfig.DEBUG) LogUtils.i("--TencentSuperPlayer--", "硬解失败");
                } else if (event == TXLiveConstants.PLAY_EVT_CHANGE_RESOLUTION) {//视频分辨率改变
                    //notifyOnVideoSizeChanged(param.getInt(TXLiveConstants.EVT_PARAM1), param.getInt(TXLiveConstants.EVT_PARAM2), getVideoSarNum(), getVideoSarNum());
                    if (BuildConfig.DEBUG) LogUtils.i("--TencentSuperPlayer--", "视频分辨率改变");
                }
            }

            @Override
            public void onNetStatus(TXVodPlayer txVodPlayer, Bundle bundle) {

            }
        });
    }

    @Override
    public void setDisplay(SurfaceHolder sh) {
        Surface surface = sh.getSurface();
        setSurface(surface);
    }

    @Override
    public void setDataSource(Context context, Uri uri) throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
        this.url = uri.getPath();
    }

    @Override
    public void setDataSource(Context context, Uri uri, Map<String, String> map) throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
        this.url = uri.toString();
    }

    @Override
    public void setDataSource(FileDescriptor fileDescriptor) throws IOException, IllegalArgumentException, IllegalStateException {
    }

    @Override
    public void setDataSource(String url) throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
        this.url = url;
    }

    @Override
    public String getDataSource() {
        return url;
    }

    @Override
    public void prepareAsync() throws IllegalStateException {
        //notifyOnPrepared();
    }

    @Override
    public void start() throws IllegalStateException {
        if (isPause) {
            // 暂停后恢复播放
            isPause = false;
            txVodPlayer.resume();
        } else {
            if (TextUtils.isEmpty(url) || surface == null) {
                canStart = true;
                return;
            }
            this.txVodPlayer.startPlay(url);
        }
    }

    @Override
    public void stop() throws IllegalStateException {
        isPause = false;
        this.txVodPlayer.stopPlay(false);
    }

    @Override
    public void pause() throws IllegalStateException {
        isPause = true;
        this.txVodPlayer.pause();
    }

    @Override
    public void setScreenOnWhilePlaying(boolean screenOn) {
        //txVodPlayer.setScreenOnWhilePlaying(screenOn);
    }

    @Override
    public int getVideoWidth() {
        return txVodPlayer.getWidth();
    }

    @Override
    public int getVideoHeight() {
        return txVodPlayer.getHeight();
    }

    @Override
    public boolean isPlaying() {
        return txVodPlayer.isPlaying();
    }

    @Override
    public void seekTo(long msec) throws IllegalStateException {
        float v = msec / 1000.0f;
        this.txVodPlayer.seek(v);//腾讯这儿是百分比
    }

    @Override
    public long getCurrentPosition() {
        return progress_ms;
        //return (long) txVodPlayer.getCurrentPlaybackTime();
    }

    @Override
    public long getDuration() {
        return duration_ms_total;
        //float duration = txVodPlayer.getDuration();
        //return (long) duration;
    }

    @Override
    public void release() {
        txVodPlayer.stopPlay(true);
        this.mIsReleased = true;
        this.resetListeners();
    }

    @Override
    public void reset() {
        //txVodPlayer.resume();//这个是恢复播放的
        this.resetListeners();
    }

    @Override
    public void setVolume(float leftVolume, float rightVolume) {
        txVodPlayer.setMute(leftVolume + rightVolume == 0);
    }

    @Override
    public int getAudioSessionId() {
        return 0;
    }

    @Override
    public MediaInfo getMediaInfo() {
        if (mediaInfo == null) {
            MediaInfo module = new MediaInfo();
            module.mVideoDecoder = "TencentSuperPlayer";
            module.mVideoDecoderImpl = "HW";
            module.mAudioDecoder = "TencentSuperPlayer";
            module.mAudioDecoderImpl = "HW";
            mediaInfo = module;
        }
        return mediaInfo;
    }

    @Override
    public void setLogEnabled(boolean b) {
    }

    @Override
    public boolean isPlayable() {
        return true;
    }

    @Override
    public void setAudioStreamType(int streamtype) {
    }

    @Override
    public void setKeepInBackground(boolean keepInBackground) {

    }

    @Override
    public int getVideoSarNum() {
        return 1;
    }

    @Override
    public int getVideoSarDen() {
        return 1;
    }

    @Override
    public void setWakeMode(Context context, int mode) {
    }

    @Override
    public void setLooping(boolean b) {
        txVodPlayer.setLoop(b);
    }

    @Override
    public boolean isLooping() {
        return txVodPlayer.isLoop();
    }

    @Override
    public ITrackInfo[] getTrackInfo() {
        return new ITrackInfo[0];
    }

    @Override
    public void setSurface(Surface surface) {
        if (surface == this.surface) return;
        this.surface = surface;
        /*if (surface == null) {
            if (!isPause) pause();
        }*/
        txVodPlayer.setSurface(surface);
        if (surface == null) return;
        if (TextUtils.isEmpty(url)) return;
        if (canStart) {
            canStart = false;
            start();
        /*} else if (isPause) {
            start();*/
        }
    }

    @Override
    public void setDataSource(IMediaDataSource iMediaDataSource) {

    }

    public TXVodPlayer getMediaPlayer() {
        return txVodPlayer;
    }
}
TencentSuperPlayerManager.java
import android.content.Context;
import android.media.AudioManager;
import android.os.Message;
import android.view.Surface;

import java.util.List;

import tv.danmaku.ijk.media.player.IMediaPlayer;

/**
 * date   : 2021/10/14 8:21 下午
 * desc   : 腾讯超级视频播放器管理器
 * version: 1.0.0
 */
public class TencentSuperPlayerManager extends BasePlayerManager {
    private TencentSuperPlayer mediaPlayer;
    //private boolean release;
    private Surface surface;

    @Override
    public IMediaPlayer getMediaPlayer() {
        return mediaPlayer;
    }

    @Override
    public void initVideoPlayer(Context context, Message message, List<VideoOptionModel> optionModelList, ICacheManager cacheManager) {
        mediaPlayer = new TencentSuperPlayer(context);
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        //release = false;
        VideoModel videoModel = (VideoModel) message.obj;
        try {
            if (videoModel.isCache() && cacheManager != null) {
                cacheManager.doCacheLogic(context, mediaPlayer, videoModel.getUrl(), videoModel.getMapHeadData(), videoModel.getCachePath());
            } else {
                mediaPlayer.setDataSource(videoModel.getUrl());
            }
            mediaPlayer.setLooping(videoModel.isLooping());
            if (videoModel.getSpeed() != 1 && videoModel.getSpeed() > 0) {
                setSpeed(videoModel.getSpeed());
            }
        } catch (Exception e) {
            if (BuildConfig.DEBUG) e.printStackTrace();
        }
        // 播放内核初始化成功
        initSuccess(videoModel);
    }

    @Override
    public void showDisplay(Message msg) {
        /*Surface holder = (Surface) msg.obj;
        if (holder == null && mediaPlayer != null && !release) {
            mediaPlayer.setSurface(null);
        } else if (holder != null) {
            if (mediaPlayer != null && holder.isValid() && !release) {
                mediaPlayer.setSurface(holder);
            }
            // if (surface != null) surface.release();
            surface = holder;
        }*/
        if (msg.obj == null && mediaPlayer != null) {
            mediaPlayer.setSurface(null);
        } else {
            Surface holder = (Surface) msg.obj;
            surface = holder;
            if (mediaPlayer != null && holder.isValid()) {
                mediaPlayer.setSurface(holder);
            }
        }
    }

    @Override
    public void setNeedMute(boolean needMute) {
        // 是否静音
        /*if (mediaPlayer != null && !release) {
            if (needMute) {
                mediaPlayer.setVolume(0, 0);
            } else mediaPlayer.setVolume(1, 1);
        }*/
        if (mediaPlayer != null) {
            if (needMute) {
                mediaPlayer.setVolume(0, 0);
            } else mediaPlayer.setVolume(1, 1);
        }
    }

    @Override
    public void setVolume(float left, float right) {

    }

    @Override
    public void releaseSurface() {
        if (surface != null) {
            //surface.release();
            surface = null;
        }
    }

    @Override
    public void release() {
        if (mediaPlayer != null) {
            //release = true;
            mediaPlayer.release();
        }
    }

    @Override
    public int getBufferedPercentage() {
        if (mediaPlayer == null) return -1;
        else return (int) mediaPlayer.getMediaPlayer().getBufferDuration();
    }

    @Override
    public long getNetSpeed() {
        //if (mediaPlayer == null)
        return 0;
    }

    @Override
    public void setSpeedPlaying(float speed, boolean soundTouch) {

    }

    @Override
    public boolean isSurfaceSupportLockCanvas() {
        return false;
    }

    @Override
    public void setSpeed(float speed, boolean soundTouch) {
        setSpeed(speed);
    }

    private void setSpeed(float speed) {
        /*if (release) {
            return;
        }*/
        if (mediaPlayer != null && mediaPlayer.getMediaPlayer() != null && mediaPlayer.isPlayable()) {
            mediaPlayer.getMediaPlayer().setRate(speed);
        }
    }

    @Override
    public void start() {
        if (mediaPlayer != null) mediaPlayer.start();
    }

    @Override
    public void stop() {
        if (mediaPlayer != null) mediaPlayer.stop();
    }

    @Override
    public void pause() {
        if (mediaPlayer != null) mediaPlayer.pause();
    }

    @Override
    public int getVideoWidth() {
        if (mediaPlayer == null) return 0;
        else return mediaPlayer.getVideoWidth();
    }

    @Override
    public int getVideoHeight() {
        if (mediaPlayer == null) return 0;
        else return mediaPlayer.getVideoHeight();
    }

    @Override
    public boolean isPlaying() {
        if (mediaPlayer == null) return false;
        else return mediaPlayer.isPlaying();
    }

    @Override
    public void seekTo(long time) {
        if (mediaPlayer == null) return;
        else mediaPlayer.seekTo(time);
    }

    @Override
    public long getCurrentPosition() {
        if (mediaPlayer == null) return 0;
        else return mediaPlayer.getCurrentPosition();
    }

    @Override
    public long getDuration() {
        if (mediaPlayer == null) return 0;
        else return mediaPlayer.getDuration();
    }

    @Override
    public int getVideoSarNum() {
        if (mediaPlayer == null) return 0;
        else return mediaPlayer.getVideoSarNum();
    }

    @Override
    public int getVideoSarDen() {
        if (mediaPlayer == null) return 0;
        else return mediaPlayer.getVideoSarDen();
    }
}

用你代码可以播,但是点击全屏会黑屏,没找到原因。你现在成功了没有