FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [View Raw Code]   [Original HTTPS Page]

GSYVideoPlayer/doc/QUESTION.md at master · CarGuo/GSYVideoPlayer · GitHub

Repository navigation

Latest commit

 

History

History
458 lines (343 loc) · 19.3 KB
  1. GSYVideoPlayer
  2. doc

QUESTION.md

File metadata and controls

458 lines (343 loc) · 19.3 KB

GSYVideoPlayer 问题集锦

Click to see the English version

v14.0.0 原生播放迁移

  • 默认 IJK 三 ABI 为 arm64-v8a / armeabi-v7a / x86_64;FFmpeg n5.1.10,OpenSSL 3.5.9。旧 armeabi / x86 不在默认整包中,未升级到 FFmpeg 5。
  • ARMv7 HTTPS 证书加载崩溃已修复,不需要删掉 ARMv7 或关闭证书校验。显式 tls_verify / ca_file 等配置会继承至 HLS 子资源;当前验证和限制见 TLS README。
  • soundtouch=1 为 0.25×–4× 软件倍速;soundtouch=0 为设备相关平台倍速。切换引擎需要排空旧音频;超出范围或平台拒绝不能视为已经应用请求值。
  • RTSP FORMAT timeout 单位为微秒;PLAYER rtsp-live-max-buffer-ms 默认 0,仅接受 0 或 500..60000 毫秒。它用于 1× 直播队列恢复,会丢弃旧媒体,不是自动重连开关。
  • RTSP 重定向覆盖初始 OPTIONS/DESCRIBE/SETUP/PLAY,不覆盖播放中 REDIRECT 或任意跨端口多控制连接。终止错误后应 reset 或重新建播放器再 seek/start/pause。
  • Codec2 的补充选择只考虑 API 29+ 平台报告的普通硬件解码器,不把 c2.android.* 软件解码器宣传成硬件加速。

完整变更、源码和已验证范围见 v14 更新说明 与 发布核对记录。

ijkplayer模式的,你可能会需要的option大全 : ff_ffplay_options.h

在线分析:https://gpac.github.io/mp4box.js/test/filereader.html

ijkplayer问题第三方总结 https://juejin.im/entry/5bc7e7d6e51d450e4f392088

0、依赖不成功的,如果是jitpach的依赖,记得在project下的build.gradle文件jitpack的依赖。(已弃用jitpack)

allprojects {
	repositories {
		...
		maven { url 'https://jitpack.io' }
	}
}

> 如果找不到依赖,出现丢包,可以看:https://github.com/CarGuo/GSYVideoPlayer/issues/4144

1、导入项目不成功?

 项目最外部有一个dependencies.gradle,所有的项目依赖都在这里面,然后参考项目根目录的build.gradle,在最顶部有apply from: 'dependencies.gradle',这样gsyVideoPlayer就可以找到对应的依赖了。gradle方便可参考察Android蹲坑的疑难杂症集锦(兼Gradle) 二

v14.0.0 默认 native 整包包含 arm64-v8a / armeabi-v7a / x86_64 三个 ABI。外部项目优先按 依赖指南 从 Maven Central 接入;需要控制体积时按目标 ABI 选择独立模块或配置 ABI 过滤,避免重复引入 native 库。

2、ClassNotFoundException和混淆

 确保你的拆包Application配置正常,若是开启混淆,确保混淆已经添加 。

而且有时候你需要的是clear一下。

# ijk JNI 层:native 侧会反射回调 Java 层,必须整包保留
-keep class tv.danmaku.ijk.media.player.** { *; }
-dontwarn tv.danmaku.ijk.media.player.**

# ---- GSYVideoPlayer 的三处关键反射点,务必保留 ----

# 1) 全屏 / 小窗:GSYBaseVideoPlayer 通过 getConstructor(Context[,Boolean]).newInstance() 复刻自身
-keep class * extends com.shuyu.gsyvideoplayer.video.base.GSYBaseVideoPlayer {
    public <init>(android.content.Context);
    public <init>(android.content.Context, java.lang.Boolean);
}

# 2) PlayerFactory:通过 Class.newInstance() 反射构造 IPlayerManager 实现
-keep class * implements com.shuyu.gsyvideoplayer.player.IPlayerManager {
    public <init>();
}
-keep interface com.shuyu.gsyvideoplayer.player.IPlayerManager { *; }

# 3) CacheFactory:通过 Class.newInstance() 反射构造 ICacheManager 实现
-keep class * implements com.shuyu.gsyvideoplayer.cache.ICacheManager {
    public <init>();
}
-keep interface com.shuyu.gsyvideoplayer.cache.ICacheManager { *; }

# Media3 官方 aar 已自带 consumer-rules,业务侧只需抑制警告
-dontwarn androidx.media3.**
-dontwarn com.google.android.exoplayer2.**

说明:不要再使用 -keep class com.shuyu.gsyvideoplayer.** { *; } 与 -keep class tv.danmaku.ijk.** { *; } 这类整包保留,它们会把整个播放器锁住导致 R8 无法优化。上面的规则只保留反射点,其余交给 R8 做常规裁剪与优化。

3、找不到对应的so或者链接so错误。

可以配置ndk abiFilters,确保使用到的so文件夹下都有对用的so文件,用Analyze Apk查看so是否应打包到各个文件夹。

参考#issue23

参考#issue24

参考ndk 过滤选择介绍

是否已经添加下方的代码到gradle

android {


        ···

    defaultConfig {
        ···
        ndk {

            //APP的build.gradle设置支持的SO库架构

            abiFilters 'armeabi', 'armeabi-v7a', 'x86'
        }

    }
}
sourceSets {
    main {
        jniLibs.srcDirs = ['libs']
    }
}

3、全屏的时候自动停止了

 是否监听了列表滑动了,在监听里更新了列表之类的。

4、播放格式与原生模块选择

v14.0.0 的 arm64/armv7a/x64 与 ex_so 使用相同 FFmpeg 5 配置,不再按普通/扩展版的 MPEG 差异选择。先检查媒体容器、编解码器及设备能力,详见 DECODERS.md。

如果拍摄的视频播放不了,可以尝试用使用系统录制的项目:VideoRecord 或者使用JAVACV录制的项目:FFmpegRecorder,测试视频是否可以播放。

黑屏相关issues: bilibili/ijkplayer#2541 bilibili/ijkplayer#1875

5、m3u8\HLS的格式视频请关闭cache

缓存不支持m3u8\HLS,播放m3u8\HLS格式,需要cacheWithPlay为false

setUp(String url, boolean cacheWithPlay····)

6、为什么拖动视屏会弹回来,因为ijk的FFMPEG对关键帧问题。

可以尝试以下设置

VideoOptionModel videoOptionModel = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "enable-accurate-seek", 1);
List<VideoOptionModel> list = new ArrayList<>();
list.add(videoOptionModel);
GSYVideoManager.instance().setOptionModelList(list);

7、视频旋转后重新开始,配置AndroidManifest.xml。

<activity
    android:name=".PlayActivity"
    android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|smallestScreenSize|uiMode"
    android:screenOrientation="portrait" />

8、弱网络加载速度太慢。

若网络环境不好,可以尝试关闭缓存来播放,因为proxy方式的边播边缓存对于网络的要求有点高。

9、如何设置cookie。

在setUp的时候,设置带有 Map<String, String> mapHeadData 参数的方法,在Ijk内部其实就是转为setOption方法。 可参考ijkPlayer的issues-1150

10、多个分片播放的功能,请查阅:

issue64 issue490 分片播放资料

11、有画面没声音,有声音没画面。

1、这种情况一般都是so里没有打包支持的格式,如果需要支持你想要的格式,可以自己重新编译so,在module配置文件加上需要额外支持的格式。github首页有编译教程。

2、某些时候,TextureView需要开启硬件加速 如application标签中的 android:hardwareAccelerated="true"

12、视频声音画面不同步。

模拟器的不接!

1、是否关闭了硬解码!

2、Activity的config是否配置了!

3、视频的分辨率和帧数是多少,机器是否支持的了

第3步可以通过尝试降低倍数:

VideoOptionModel videoOptionModel =
        new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 50);
List<VideoOptionModel> list = new ArrayList<>();
list.add(videoOptionModel);
GSYVideoManager.instance().setOptionModelList(list);

13、url视频文件中文名。

对于如http://xxxxxxx.中文.mp4的url,如果出现 http 400 error的情况,请自行转换中文url到url编码; 如 http://tool.oschina.net/encode?type=4 这里转化。

14、rtsp播放失败问题

#232

#207

15、m3u8拖动seek之后,加载很长时间

bilibili/ijkplayer#2874

#252

16、播放本地m3u8有问题

VideoOptionModel videoOptionModel =
        new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "protocol_whitelist", crypto,file,http,https,tcp,tls,udp);
VideoOptionModel videoOptionModel2 =
        new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "allowed_extensions", ALL);
List<VideoOptionModel> list = new ArrayList<>();
list.add(videoOptionModel);
list.add(videoOptionModel2);
GSYVideoManager.instance().setOptionModelList(list);

17、rtsp连接有问题

VideoOptionModel videoOptionModel = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_transport", "tcp");
List<VideoOptionModel> list = new ArrayList<>();
list.add(videoOphtionModel);
GSYVideoManager.instance().setOptionModelList(list);

更多优化(一个setOption对应gsy中VideoOptionModel)

//硬解码:1、打开,0、关闭
//mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1);
//软解码:1、打开,0、关闭
//mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "videotoolbox", 0);

//rtsp设置 https://ffmpeg.org/ffmpeg-protocols.html#rtsp
mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_transport", "tcp");
mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_flags", "prefer_tcp");

mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "allowed_media_types", "video"); //根据媒体类型来配置
// 14.0.0:FFmpeg 5 的 RTSP timeout 单位是微秒:20_000_000 = 20 秒;20_000 只有 20 毫秒。
// 新版会保留此选项,不再把 RTSP timeout 当作 RTMP 参数删除。请检查旧配置,勿自动换算。
mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "timeout", 20_000_000L);
mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "buffer_size", 1316);
mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "infbuf", 1);  // 无限读
mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzemaxduration", 100L);
mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "probesize", 10240L);
mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "flush_packets", 1L);
// 可按业务需要关闭 packet-buffering;这不是 rtsp-live-max-buffer-ms 的必需条件。
mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", 0L);
mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 1L);

对应

List<VideoOptionModel> list = new ArrayList<>();
VideoOptionModel videoOptionMode01 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "fast", 1);//不额外优化
list.add(videoOptionMode01);
VideoOptionModel videoOptionMode02 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "probesize", 200);//10240
list.add(videoOptionMode02);
VideoOptionModel videoOptionMode03 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "flush_packets", 1);
list.add(videoOptionMode03);
//pause output until enough packets have been read after stalling
VideoOptionModel videoOptionMode04 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", 0);//是否开启缓冲
list.add(videoOptionMode04);
//drop frames when cpu is too slow:0-120
VideoOptionModel videoOptionMode05 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 1);//丢帧,太卡可以尝试丢帧
list.add(videoOptionMode05);
//automatically start playing on prepared
VideoOptionModel videoOptionMode06 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 1);
list.add(videoOptionMode06);
VideoOptionModel videoOptionMode07 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_CODEC, "skip_loop_filter", 48);//默认值48
list.add(videoOptionMode07);
//max buffer size should be pre-read:默认为15*1024*1024
VideoOptionModel videoOptionMode11 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max-buffer-size", 0);//最大缓存数
list.add(videoOptionMode11);
VideoOptionModel videoOptionMode12 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "min-frames", 2);//默认最小帧数2
list.add(videoOptionMode12);
VideoOptionModel videoOptionMode13 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max_cached_duration", 30);//最大缓存时长
list.add(videoOptionMode13);
//input buffer:don't limit the input buffer size (useful with realtime streams)
VideoOptionModel videoOptionMode14 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "infbuf", 1);//是否限制输入缓存数
list.add(videoOptionMode14);
VideoOptionModel videoOptionMode15 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "fflags", "nobuffer");
list.add(videoOptionMode15);
VideoOptionModel videoOptionMode16 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_transport", "tcp");//tcp传输数据
list.add(videoOptionMode16);
VideoOptionModel videoOptionMode17 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzedmaxduration", 100);//分析码流时长:默认1024*1000
list.add(videoOptionMode17);

GSYVideoManager.instance().setOptionModelList(list);

18、url切换400/404(http与https域名共用等)

        VideoOptionModel videoOptionModel =
                new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "dns_cache_clear", 1);
        List<VideoOptionModel> list = new ArrayList<>();
        list.add(videoOptionModel);
        VideoOptionModel videoOptionModel2 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "dns_cache_timeout", -1);
        list.add(videoOptionModel2);
        GSYVideoManager.instance().setOptionModelList(list);

19、全屏与非全屏的同步问题

有一些自定义操作,需要全屏与非全屏切换之间做同步处理,具体操作是重载下面两个方法,实现自己的自定义操作,详细可参考demo。 外部获取当前播放器,推荐使用play.getCurPlay().xxxxxx

/**
 * 全屏时将对应处理参数逻辑赋给全屏播放器
 *
 * @param context
 * @param actionBar
 * @param statusBar
 * @return
 */
@Override
public GSYBaseVideoPlayer startWindowFullscreen(Context context, boolean actionBar, boolean statusBar) {
    SmartPickVideo sampleVideo = (SmartPickVideo) super.startWindowFullscreen(context, actionBar, statusBar);
    sampleVideo.mSourcePosition = mSourcePosition;
    sampleVideo.mType = mType;
    sampleVideo.mUrlList = mUrlList;
    sampleVideo.mTypeText = mTypeText;
    sampleVideo.mSwitchSize.setText(mTypeText);
    return sampleVideo;
}

/**
 * 推出全屏时将对应处理参数逻辑返回给非播放器
 *
 * @param oldF
 * @param vp
 * @param gsyVideoPlayer
 */
@Override
protected void resolveNormalVideoShow(View oldF, ViewGroup vp, GSYVideoPlayer gsyVideoPlayer) {
    super.resolveNormalVideoShow(oldF, vp, gsyVideoPlayer);
    if (gsyVideoPlayer != null) {
        SmartPickVideo sampleVideo = (SmartPickVideo) gsyVideoPlayer;
        mSourcePosition = sampleVideo.mSourcePosition;
        mType = sampleVideo.mType;
        mTypeText = sampleVideo.mTypeText;
        mSwitchSize.setText(mTypeText);
        setUp(mUrlList, mCache, mCachePath, mTitle);
    }
}

20、精准的某个时间开始播放

注意,这个是全局地设置,设置之后如果不需要需要清除这个item。

VideoOptionModel videoOptionModel =
                new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "seek-at-start", startPosition);
        List<VideoOptionModel> list = new ArrayList<>();
        list.add(videoOptionModel);
        GSYVideoManager.instance().setOptionModelList(list);

21、AudioManager泄漏

https://stackoverflow.com/questions/6445052/android-context-memory-leak-listview-due-to-audiomanager

22、重连次数

VideoOptionModel videoOptionModel =
                new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER,"reconnect",5);
        List<VideoOptionModel> list = new ArrayList<>();
        list.add(videoOptionModel);
        GSYVideoManager.instance().setOptionModelList(list);

22、ijk 模式的 mkv 字幕

出了选择 track 之外,还可以配置

VideoOptionModel videoOptionModel =
 new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "subtitle", 1);
List<VideoOptionModel> list = new ArrayList<>();
list.add(videoOptionModel);
GSYVideoManager.instance().setOptionModelList(list);

23、封面到播放过程的黑屏问题

#3941 (comment)

24、其他问题

#2997 (comment)

25、seek 后花屏、死循环 buffer 问题

invalid dts/pts combination 740157300
  • dts没有值时,返回回去后,解码状态全部进行了reset,则送入的第一帧信息应该为关键帧,否则该帧需要参考其他帧,产生花屏。
  • dts时间戳有误,将出现dts转化为微秒后永远小于seek传入时间问题,则永远无法返回packet,导致seek僵死。
  • 判断packet是否为关键帧,忽略了该packet是否为视频,如果该packet为音频并且flag & AV_PKT_FLAG_KEY的结果为真,则将返回该packet并清空seek标准。后续读到的视频也有非关键帧的可能,从而导致花屏。

26、增加 ijk 代理支持

VideoOptionModel videoOptionModel2 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "http_proxy", "http://192.168.0.116:8888 ");
List<VideoOptionModel> list = new ArrayList<>();
list.add(videoOptionModel2);
GSYVideoManager.instance().setOptionModelList(list);

27、ijk 出现切换音轨失败问题 #3790

        VideoOptionModel videoOptionModel2 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "min-frames", 25);
        List<VideoOptionModel> list = new ArrayList<>();
        list.add(videoOptionModel2);
        GSYVideoManager.instance().setOptionModelList(list);
       binding.change.setOnClickListener(new View.OnClickListener() {
            int index = 0;

            @Override
            public void onClick(View view) {
                IjkMediaPlayer player =  ((IjkMediaPlayer)((IjkPlayerManager)binding.detailPlayer.getGSYVideoManager().getPlayer() ).getMediaPlayer());
                player.selectTrack(1);
            }
        });

28、

更多配置

更多配置可通过下方链接和图片参考配置


Back | FazBrowse Home | New Git URL