## GSYVideoPlayer FAQ **[Click to see the Chinese version](QUESTION.md)** ### v14.0.0 native playback migration - Default IJK ABIs are `arm64-v8a` / `armeabi-v7a` / `x86_64`, using FFmpeg n5.1.10 / OpenSSL 3.5.9. Legacy `armeabi` / `x86` are outside the default aggregate and not migrated to FFmpeg 5. - ARMv7 HTTPS certificate loading is fixed; removing ARMv7 or disabling verification is unnecessary. Explicit `tls_verify` / `ca_file` settings follow nested HLS resources; see [current TLS results and limits](../tests/tls-native/README.md). - `soundtouch=1` selects 0.25x–4x software tempo; `soundtouch=0` uses device-dependent platform rates. Handoff drains old audio; invalid/rejected requests must not be reported as applied. - RTSP FORMAT `timeout` is in microseconds. PLAYER `rtsp-live-max-buffer-ms` defaults to `0` and accepts only `0` or `500..60000` ms. Recovery at 1x discards old media; it is not an automatic reconnect option. - Redirects cover initial OPTIONS/DESCRIBE/SETUP/PLAY, not playback-time REDIRECT or arbitrary cross-port multi-control sessions. Reset/reopen after a terminal error before seek/start/pause. - Additional Codec2 selection considers regular platform-reported hardware decoders on API 29+, excluding software codecs such as `c2.android.*`. See the [v14 changelog](UPDATE_VERSION_EN.md#v1400-2026-10-10) and [release audit](V14_RELEASE_REVIEW.md) for source identity and verification scope. #### ijkplayer mode, you may need a complete list of options: [ff_ffplay_options.h](https://github.com/CarGuo/ijkplayer/blob/df3f5ca6ed56419e7af04de0fd3a7474bb41950b/ijkmedia/ijkplayer/ff_ffplay_options.h) > Online analysis: https://gpac.github.io/mp4box.js/test/filereader.html **Third-party summary of ijkplayer issues https://juejin.im/entry/5bc7e7d6e51d450e4f392088** #### 0. If the dependency is unsuccessful, and it is a jitpack dependency, remember to add the jitpack dependency in the build.gradle file under the project. (jitpack is deprecated) ``` allprojects { repositories { ... maven { url 'https://jitpack.io' } } } > If you can't find the dependency and there are missing packages, you can see: https://github.com/CarGuo/GSYVideoPlayer/issues/4144 ``` #### 1. Failed to import the project? There is a dependencies.gradle in the outermost part of the project, and all project dependencies are in it. Then refer to the build.gradle in the root directory of the project. There is apply from: 'dependencies.gradle' at the top, so that gsyVideoPlayer can find the corresponding dependencies. For gradle convenience, you can refer to [Collection of difficult and miscellaneous diseases of Android squatting (and Gradle) II](http://www.jianshu.com/p/86e4b336c17d) The v14.0.0 default native aggregate contains three ABIs: `arm64-v8a` / `armeabi-v7a` / `x86_64`. External projects should follow the [dependency guide](DEPENDENCIES_EN.md) for Maven Central integration. To reduce package size, select individual ABI modules or configure ABI filters, avoiding duplicate native libraries. #### 2. ClassNotFoundException and obfuscation Make sure that your unpacking Application configuration is normal. If obfuscation is enabled, make sure that obfuscation has been added. And sometimes what you need is to clear it. ``` # ijk JNI: native side reflects back into Java, keep the whole package -keep class tv.danmaku.ijk.media.player.** { *; } -dontwarn tv.danmaku.ijk.media.player.** # ---- Three reflection hotspots inside GSYVideoPlayer, MUST keep ---- # 1) Fullscreen / small-window: GSYBaseVideoPlayer re-instantiates itself via # getConstructor(Context[, Boolean]).newInstance() -keep class * extends com.shuyu.gsyvideoplayer.video.base.GSYBaseVideoPlayer { public (android.content.Context); public (android.content.Context, java.lang.Boolean); } # 2) PlayerFactory instantiates IPlayerManager implementations via Class.newInstance() -keep class * implements com.shuyu.gsyvideoplayer.player.IPlayerManager { public (); } -keep interface com.shuyu.gsyvideoplayer.player.IPlayerManager { *; } # 3) CacheFactory instantiates ICacheManager implementations via Class.newInstance() -keep class * implements com.shuyu.gsyvideoplayer.cache.ICacheManager { public (); } -keep interface com.shuyu.gsyvideoplayer.cache.ICacheManager { *; } # Media3 aar already ships its own consumer-rules, just silence warnings here -dontwarn androidx.media3.** -dontwarn com.google.android.exoplayer2.** ``` > Note: do NOT use broad rules like `-keep class com.shuyu.gsyvideoplayer.** { *; }` > or `-keep class tv.danmaku.ijk.** { *; }` anymore. They freeze the entire player > and defeat R8 optimizations. The rules above keep only the reflection surface > and let R8 shrink / optimize everything else. #### 3. The corresponding so cannot be found or the so is linked incorrectly. You can configure ndk abiFilters to ensure that there are corresponding so files in the so folder used. Use Analyze Apk to check whether so should be packaged into each folder. Refer to [#issue23](https://github.com/CarGuo/GSYVideoPlayer/issues/23) Refer to [#issue24](https://github.com/CarGuo/GSYVideoPlayer/issues/24) Refer to [ndk filter selection introduction](https://www.diycode.cc/topics/691) Have you added the following code to gradle ``` android { ··· defaultConfig { ··· ndk { //APP's build.gradle sets the supported SO library architecture abiFilters 'armeabi', 'armeabi-v7a', 'x86' } } } ``` ``` sourceSets { main { jniLibs.srcDirs = ['libs'] } } ``` #### 3. It stopped automatically in full screen Did you monitor the list sliding and update the list in the monitoring. #### 4. Media formats and native module selection v14.0.0 arm64/armv7a/x64 and ex_so share the same FFmpeg 5 profile. Check container, codec and device capabilities rather than the former standard/extended MPEG distinction; see [DECODERS_EN.md](DECODERS_EN.md). If the recorded video cannot be played, you can try to use the system recording project: [VideoRecord](https://github.com/CarGuo/VideoRecord) Or use the JAVACV recording project: [FFmpegRecorder](https://github.com/CrazyOrr/FFmpegRecorder), to test whether the video can be played. Black screen related issues: https://github.com/Bilibili/ijkplayer/issues/2541 https://github.com/Bilibili/ijkplayer/pull/1875 #### 5. m3u8\HLS format video please turn off cache Cache does not support m3u8\HLS, to play m3u8\HLS format, you need cacheWithPlay to be false ``` setUp(String url, boolean cacheWithPlay····) ``` #### 6. Why does the video pop back when dragging, because of the key frame problem of ijk's FFMPEG. You can try the following settings ``` VideoOptionModel videoOptionModel = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "enable-accurate-seek", 1); List list = new ArrayList<>(); list.add(videoOptionModel); GSYVideoManager.instance().setOptionModelList(list); ``` #### 7. The video starts again after rotation, configure AndroidManifest.xml. ``` ``` #### 8. The loading speed of a weak network is too slow. If the network environment is not good, you can try to turn off the cache to play, because the proxy method of playing while caching has high requirements on the network. #### 9. How to set cookies. When setUp, set the method with the Map mapHeadData parameter, which is actually converted to the setOption method inside Ijk. You can refer to ijkPlayer's [issues-1150](https://github.com/Bilibili/ijkplayer/issues/1150) #### 10. For the function of playing multiple fragments, please refer to: [issue64](https://github.com/CarGuo/GSYVideoPlayer/issues/64) [issue490](https://github.com/Bilibili/ijkplayer/issues/490) [Fragmented playback data](http://www.jianshu.com/p/ea794a357b48) #### 11. There is picture but no sound, there is sound but no picture. 1. This situation is generally because the supported format is not packaged in so. If you need to support the format you want, you can recompile so yourself and add the additional supported format to the module configuration file. There is a compilation tutorial on the github homepage. [2. Sometimes, TextureView needs to enable hardware acceleration](https://github.com/CarGuo/GSYVideoPlayer/issues/266) such as `android:hardwareAccelerated="true"` in the application tag #### 12. The video sound and picture are not synchronized. The simulator does not accept it! 1. Is the hard decoding turned off! 2. Is the config of the Activity configured! 3. What is the resolution and frame rate of the video, and does the machine support it? Step 3 can be tried by reducing the multiple: ``` VideoOptionModel videoOptionModel = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 50); List list = new ArrayList<>(); list.add(videoOptionModel); GSYVideoManager.instance().setOptionModelList(list); ``` #### 13. The url video file has a Chinese name. For urls such as http://xxxxxxx.Chinese.mp4, if a http 400 error occurs, please convert the Chinese url to url encoding yourself; For example, http://tool.oschina.net/encode?type=4 is converted here. #### 14. rtsp playback failure problem https://github.com/CarGuo/GSYVideoPlayer/issues/232 https://github.com/CarGuo/GSYVideoPlayer/issues/207 #### 15. m3u8 takes a long time to load after dragging seek https://github.com/Bilibili/ijkplayer/issues/2874 https://github.com/CarGuo/GSYVideoPlayer/issues/252 #### 16. There is a problem playing local 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 list = new ArrayList<>(); list.add(videoOptionModel); list.add(videoOptionModel2); GSYVideoManager.instance().setOptionModelList(list); ``` #### 17. There is a problem with rtsp connection ``` VideoOptionModel videoOptionModel = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_transport", "tcp"); List list = new ArrayList<>(); list.add(videoOphtionModel); GSYVideoManager.instance().setOptionModelList(list); ``` More optimization (one setOption corresponds to VideoOptionModel in gsy) ``` //Hard decoding: 1, on, 0, off //mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1); //Soft decoding: 1, on, 0, off //mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "videotoolbox", 0); //rtsp settings 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"); //Configure according to media type // 14.0.0: FFmpeg 5 RTSP timeout is in microseconds: 20_000_000 = 20 seconds. // The option is now preserved for RTSP; review old values without automatic conversion. 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); // Infinite read 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); // Disable packet-buffering only when needed; rtsp-live-max-buffer-ms does not require it. mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", 0L); mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 1L); ``` corresponding ``` List list = new ArrayList<>(); VideoOptionModel videoOptionMode01 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "fast", 1);//No extra optimization 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);//Whether to enable buffering list.add(videoOptionMode04); //drop frames when cpu is too slow:0-120 VideoOptionModel videoOptionMode05 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 1);//Frame dropping, if it is too stuck, you can try to drop frames 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);//Default value 48 list.add(videoOptionMode07); //max buffer size should be pre-read:Default is 15*1024*1024 VideoOptionModel videoOptionMode11 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max-buffer-size", 0);//Maximum cache number list.add(videoOptionMode11); VideoOptionModel videoOptionMode12 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "min-frames", 2);//Default minimum frame number 2 list.add(videoOptionMode12); VideoOptionModel videoOptionMode13 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max_cached_duration", 30);//Maximum cache duration 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);//Whether to limit the input cache number 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 data transmission list.add(videoOptionMode16); VideoOptionModel videoOptionMode17 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzedmaxduration", 100);//Analysis stream duration: default 1024*1000 list.add(videoOptionMode17); GSYVideoManager.instance().setOptionModelList(list); ``` #### 18. url switching 400/404 (http and https domain names are shared, etc.) ``` VideoOptionModel videoOptionModel = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "dns_cache_clear", 1); List 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. Synchronization problem between full screen and non-full screen There are some custom operations that need to be synchronized between full screen and non-full screen switching. The specific operation is to overload the following two methods to implement your own custom operations. For details, please refer to the demo. To get the current player externally, it is recommended to use `play.getCurPlay().xxxxxx` ``` /** * When in full screen, assign the corresponding processing parameter logic to the full screen player * * @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; } /** * When exiting full screen, return the corresponding processing parameter logic to the non-player * * @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. Start playing at a precise time Note that this is a global setting. After setting, you need to clear this item if you don't need it. ``` VideoOptionModel videoOptionModel = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "seek-at-start", startPosition); List list = new ArrayList<>(); list.add(videoOptionModel); GSYVideoManager.instance().setOptionModelList(list); ``` #### 21. AudioManager leak https://stackoverflow.com/questions/6445052/android-context-memory-leak-listview-due-to-audiomanager #### 22. Number of reconnections ``` VideoOptionModel videoOptionModel = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER,"reconnect",5); List list = new ArrayList<>(); list.add(videoOptionModel); GSYVideoManager.instance().setOptionModelList(list); ``` #### 22. mkv subtitles in ijk mode In addition to selecting a track, you can also configure ``` VideoOptionModel videoOptionModel = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "subtitle", 1); List list = new ArrayList<>(); list.add(videoOptionModel); GSYVideoManager.instance().setOptionModelList(list); ``` #### 23. Black screen problem from cover to playback https://github.com/CarGuo/GSYVideoPlayer/issues/3941#issuecomment-1972409662 ### 24. Other issues https://github.com/CarGuo/GSYVideoPlayer/issues/2997#issuecomment-711480841 ### 25. Garbled screen after seek, infinite loop buffer problem ``` invalid dts/pts combination 740157300 ``` - When dts has no value, after returning, the decoding state is all reset, then the first frame of information sent should be a key frame, otherwise this frame needs to refer to other frames, resulting in a garbled screen. - The dts timestamp is wrong, which will cause the dts to be converted to microseconds and always be less than the time passed in by seek, so the packet can never be returned, causing the seek to freeze. - When judging whether the packet is a key frame, it ignores whether the packet is video. If the packet is audio and the result of flag & AV_PKT_FLAG_KEY is true, the packet will be returned and the seek standard will be cleared. The subsequent video read may also have non-key frames, thus causing a garbled screen. ### 26. Add ijk proxy support ```java VideoOptionModel videoOptionModel2 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "http_proxy", "http://192.168.0.116:8888 "); List list = new ArrayList<>(); list.add(videoOptionModel2); GSYVideoManager.instance().setOptionModelList(list); ``` ### 27. ijk has a problem of switching audio tracks [#3790](https://github.com/CarGuo/GSYVideoPlayer/issues/3790) ```java VideoOptionModel videoOptionModel2 = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "min-frames", 25); List list = new ArrayList<>(); list.add(videoOptionModel2); GSYVideoManager.instance().setOptionModelList(list); ``` ```java 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. #### More configurations For more configurations, please refer to the links and pictures below ##### [ff_ffplay_options](https://github.com/CarGuo/ijkplayer/blob/df3f5ca6ed56419e7af04de0fd3a7474bb41950b/ijkmedia/ijkplayer/ff_ffplay_options.h) ![](https://raw.githubusercontent.com/CarGuo/GSYVideoPlayer/master/img/code/option1.jpg) ![](https://raw.githubusercontent.com/CarGuo/GSYVideoPlayer/master/img/code/option2.jpg)