ijkplayer模式的,你可能会需要的option大全 : ff_ffplay_options.h
ijkplayer问题第三方总结 https://juejin.im/entry/5bc7e7d6e51d450e4f392088
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
项目最外部有一个dependencies.gradle,所有的项目依赖都在这里面,然后参考项目根目录的build.gradle,在最顶部有apply from: 'dependencies.gradle',这样gsyVideoPlayer就可以找到对应的依赖了。gradle方便可参考察Android蹲坑的疑难杂症集锦(兼Gradle) 二
其次,因为so有五个平台,远程依赖库比较大,依赖的时候如果有条件,可以开启vpn,用L2TP协议,依赖下载会快一些。
确保你的拆包Application配置正常,若是开启混淆,确保混淆已经添加 。
而且有时候你需要的是clear一下。
-keep class tv.danmaku.ijk.** { *; }
-dontwarn tv.danmaku.ijk.**
-keep class com.shuyu.gsyvideoplayer.** { *; }
-dontwarn com.shuyu.gsyvideoplayer.**
可以配置ndk abiFilters,确保使用到的so文件夹下都有对用的so文件,用Analyze Apk查看so是否应打包到各个文件夹。
参考#issue23
参考#issue24
是否已经添加下方的代码到gradle
android {
···
defaultConfig {
···
ndk {
//APP的build.gradle设置支持的SO库架构
abiFilters 'armeabi', 'armeabi-v7a', 'x86'
}
}
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
是否监听了列表滑动了,在监听里更新了列表之类的。
如果拍摄的视频播放不了,可以尝试用使用系统录制的项目:VideoRecord 或者使用JAVACV录制的项目:FFmpegRecorder,测试视频是否可以播放。
黑屏相关issues: bilibili/ijkplayer#2541 bilibili/ijkplayer#1875
缓存不支持m3u8\HLS,播放m3u8\HLS格式,需要cacheWithPlay为false
setUp(String url, boolean cacheWithPlay····)
可以尝试以下设置
VideoOptionModel videoOptionModel = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "enable-accurate-seek", 1);
List<VideoOptionModel> list = new ArrayList<>();
list.add(videoOptionModel);
GSYVideoManager.instance().setOptionModelList(list);
<activity
android:name=".PlayActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|smallestScreenSize|uiMode"
android:screenOrientation="portrait" />
若网络环境不好,可以尝试关闭缓存来播放,因为proxy方式的边播边缓存对于网络的要求有点高。
在setUp的时候,设置带有 Map<String, String> mapHeadData 参数的方法,在Ijk内部其实就是转为setOption方法。 可参考ijkPlayer的issues-1150
1、这种情况一般都是so里没有打包支持的格式,如果需要支持你想要的格式,可以自己重新编译so,在module配置文件加上需要额外支持的格式。github首页有编译教程。
2、某些时候,TextureView需要开启硬件加速 如application标签中的 android:hardwareAccelerated="true"
模拟器的不接!
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);
对于如http://xxxxxxx.中文.mp4的url,如果出现 http 400 error的情况,请自行转换中文url到url编码; 如 http://tool.oschina.net/encode?type=4 这里转化。
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);
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"); //根据媒体类型来配置
mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "timeout", 20000);
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);
// 关闭播放器缓冲,这个必须关闭,否则会出现播放一段时间后,一直卡主,控制台打印 FFP_MSG_BUFFERING_START
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);
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);
有一些自定义操作,需要全屏与非全屏切换之间做同步处理,具体操作是重载下面两个方法,实现自己的自定义操作,详细可参考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);
}
}
注意,这个是全局地设置,设置之后如果不需要需要清除这个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);
VideoOptionModel videoOptionModel =
new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER,"reconnect",5);
List<VideoOptionModel> list = new ArrayList<>();
list.add(videoOptionModel);
GSYVideoManager.instance().setOptionModelList(list);
出了选择 track 之外,还可以配置
VideoOptionModel videoOptionModel =
new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "subtitle", 1);
List<VideoOptionModel> list = new ArrayList<>();
list.add(videoOptionModel);
GSYVideoManager.instance().setOptionModelList(list);
invalid dts/pts combination 740157300
- dts没有值时,返回回去后,解码状态全部进行了reset,则送入的第一帧信息应该为关键帧,否则该帧需要参考其他帧,产生花屏。
- dts时间戳有误,将出现dts转化为微秒后永远小于seek传入时间问题,则永远无法返回packet,导致seek僵死。
- 判断packet是否为关键帧,忽略了该packet是否为视频,如果该packet为音频并且flag & AV_PKT_FLAG_KEY的结果为真,则将返回该packet并清空seek标准。后续读到的视频也有非关键帧的可能,从而导致花屏。
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);
}
});
更多配置可通过下方链接和图片参考配置