Fix fullscreen replay failure after video completion#4212
Fix fullscreen replay failure after video completion#4212
Conversation
When in fullscreen mode after video auto-completes, clicking replay would cause the video to get stuck. The issue was in startPrepare() which would call onCompletion() on the current listener, even when it was the same fullscreen player trying to replay itself. This caused unnecessary state reset and texture view removal, preventing proper video playback. The fix adds a check to ensure onCompletion() is only called when the current listener is different from the player initiating the new playback. Co-authored-by: CarGuo <10770362+CarGuo@users.noreply.github.com>
…playback Move addTextureView() to be called BEFORE getGSYVideoManager().start() in startAfterPrepared(). This ensures the surface is created and ready before playback begins, fixing the issue where video would freeze (progress bar moves but video frame is frozen) when replaying in fullscreen mode after auto-completion. This issue was introduced in v11.2.0 with the timing of texture view creation relative to playback start. Co-authored-by: CarGuo <10770362+CarGuo@users.noreply.github.com>
感谢反馈和日志!经过对比 v11.1.0 和 v11.2.0 的代码,我发现问题在于 新的修复 (f42ad2c) 将 Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
@copilot 但是照你这么说为什么非全屏的时候不会? |
你说得对,如果是 我已经还原了代码。仔细查看差异后,我发现关键区别在于:
这意味着全屏模式下 listener 的管理方式不同。问题可能出在 v11.2.0 引入的 AudioFocusManager 重构,而不是 texture view 的顺序。 能否提供更多信息:使用的是 IJK 播放器还是 ExoPlayer?以及问题发生时完整的日志?这样我可以更准确地定位问题。 |
Reverted the addTextureView() order change as it wouldn't explain why only fullscreen mode is affected. The issue must be related to the different listener management in fullscreen vs non-fullscreen mode. Co-authored-by: CarGuo <10770362+CarGuo@users.noreply.github.com>
… fullscreen mode The issue was introduced in v11.2.0 when onDetachedFromWindow() was modified to call releaseAudioFocusManager() unconditionally. When entering fullscreen, the original player's view is detached, which incorrectly released the AudioFocusManager. This caused the fullscreen player to fail when trying to replay after video completion. The fix adds a condition to only release AudioFocusManager when NOT in fullscreen mode, preserving it for the fullscreen player to use. Co-authored-by: CarGuo <10770362+CarGuo@users.noreply.github.com>
|
找到问题根源了!问题出在 v11.2.0 引入的 当进入全屏时,原始播放器的 view 会从 window 中 detach,这会触发 非全屏模式不受影响是因为播放器 view 在正常播放过程中不会被 detach。 修复 (4f2b67c): 在 Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
When replaying in fullscreen mode, onAudioFocusLossTransient() was being triggered during the preparation phase. This caused onVideoPause() to set mPauseBeforePrepared = true, which resulted in the video being paused immediately after preparation instead of playing. The fix adds a state check in onAudioFocusLossTransient() to skip calling onVideoPause() when the player is in CURRENT_STATE_PREPAREING state. Co-authored-by: CarGuo <10770362+CarGuo@users.noreply.github.com>
找到根本原因了!问题是在准备阶段 修复 (3bda8a5): 在 Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
@copilot 你这样修改不对,问题是在 GSYAudioFocusManager 的 触发,而来源是 mInternalListener 的 new Handler(Looper.getMainLooper()).post(() -> handleAudioFocusChange(focusChange, listener)); 这时候触发的是 CURRENT_STATE_PLAYING ,也可能是 CURRENT_STATE_PREPAREING ,所以这是问题的根源 我觉得应该这么改才对? 你帮我看看还有没有其他类似的隐患 |
Add listener identity check (listener == this) to ensure only the currently active player responds to audio focus changes. This fixes the issue where asynchronous audio focus callbacks from GSYAudioFocusManager could affect the wrong player instance during fullscreen transitions. Both onAudioFocusLoss() and onAudioFocusLossTransient() now verify that the current GSYVideoManager listener is the same instance before calling onVideoPause(). Co-authored-by: CarGuo <10770362+CarGuo@users.noreply.github.com>
已按照您的建议修复 (cc8646d)。在 GSYMediaPlayerListener listener = getGSYVideoManager().listener();
if (listener != null && listener == this) {
listener.onVideoPause();
}检查了其他类似的方法:
这两个空方法如果将来被实现,也应该添加同样的 |
|
@copilot 但是这么改又带来了新的问题,全屏的时候,如果有第三方播放器播放,这时候无法进入暂停,这个要怎么适配? |
Changed the audio focus loss callbacks to check isPlaying() instead of listener identity. This fixes two issues: 1. In preparation phase, isPlaying() returns false, so async callbacks won't incorrectly trigger pause and set mPauseBeforePrepared 2. In fullscreen mode when third-party player starts, if current player is actually playing, it will correctly pause The isPlaying() check ensures only actively playing instances respond to audio focus changes, regardless of which player instance receives the callback. Co-authored-by: CarGuo <10770362+CarGuo@users.noreply.github.com>
已修复 (65dd118)。改用 if (listener != null && getGSYVideoManager().isPlaying()) {
listener.onVideoPause();
}这样解决了两个问题:
|
isPlaying()state in audio focus callbacksIssue Description
在 DetailPlayer 下,点击正常播放,然后进入全屏,播放结束后,再点击播放,就会出现异常,无法继续播放,画面卡住,但是再非全屏不会有这个问题
(In DetailPlayer, after playing normally and then entering fullscreen, when the playback ends and you click play again, an error occurs where playback cannot continue and the video gets stuck. This issue does not occur in non-fullscreen mode.)
Root Cause
The issue is in
GSYAudioFocusManagerwheremInternalListenerusesHandler(Looper.getMainLooper()).post()to send callbacks asynchronously. This causeshandleAudioFocusChangeto potentially triggeronAudioFocusLossTransient()at the wrong time.Solution Evolution
listener == this- but this broke fullscreen mode where third-party player starting wouldn't pause current playergetGSYVideoManager().isPlaying()insteadThis solves both problems:
isPlaying()returns false, so async callbacks won't trigger incorrect pauseSecurity Summary
No security vulnerabilities were introduced or discovered in this change.
Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.