Repository navigation
Conversation
The playback watchdog only ever fires on a PlayerError. When a browser stops consuming frames without raising any event (common on mobile with these MP2-audio / 1080i multicast channels), nothing retries and the user has to switch channels by hand to get the picture back. Detect that case in the MSE controller and turn it into the error the stock player already retries on, so the existing retry path issues a new request. - watchdog requires >= 8 s of continuous playback in the current session before it judges anything, so startup / channel switching / post-rebuild (currentTime back to ~0) never enters monitoring: the stock startup path is untouched - only the on-screen <video> is judged: with dual A/B slots the detached slot keeps a frozen clock and must not raise errors for the playing one - 1 s without progress => suspend() first (release our own connection so the retry does not stack up against maxclients) then MEDIA_MSE_ERROR - MAX_RETRIES 3 -> 100 (the stock player resets the baseline after 30 s of stable playback, so this only bounds a truly hopeless stream)
…lace Reloading segments inside the wedged slot keeps the same video element, worker and audio context, and recovers slowly. Load into the hidden A/B slot and hard-switch when it is ready — the same path as tapping a channel — which also releases the frozen connection instead of stacking a retry on top of it. The MSE watchdog now asks the page to do this, falling back to the retry path when nothing handles the event.
A silent freeze is not the only failure mode: sometimes loading never produces video at all and the page sits on 'buffering' indefinitely. Track when the visible slot started loading and, if no video has been produced after 12 s, take the same recovery path. The clock is (re)started while the slot is off screen, so the hidden slot of a seamless switch never trips it, and the normal startup path (a few seconds) is untouched.
Author
|
已被新方案取代:判据改为「没收到数据」+ 0.2s 预建 / 0.8s 切换 + 静默恢复,详见后续 PR。 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
现象
手机浏览器(Android/鸿蒙 Chromium)播放直播台,约 1~2 分钟后画面定格,且不恢复,必须手动切台才回来。
同一时刻的客观状态:
/status/sse里该客户端队列 0~80 KB(上限 4.7 MB)、currentBandwidth稳定 ~1.1 MB/s、slow=0、连接不掉;/player也不显示错误页。根因
video-player.tsx的重试只挂在handlePlayerError(PlayerError)上:MSE 报错、加载失败才会走到scheduleRetryReload。而这类静默停读(媒体时钟不再前进、但网络层的读取还在继续)不产生任何
PlayerError⇒MAX_RETRIES一次都不会触发,只能等用户手动切台。改动
1.
playback-engine/mse/playback-controller.ts:把静默停读接入现有重试链路新增播放进度看门狗,每秒检查
video.currentTime,并有三条硬约束:currentTime归零,永远进不了监控 —— 原有起播流程(含 MP2 软解与视频对齐时的 1/16 减速)一字未改;<video>:无缝切台用 A/B 双 slot,旧元素仍留在 DOM 里但已离屏,其时钟必然冻结,不能拿它判定;suspend()释放当前连接(否则冻结的连接还占着服务端maxclients名额,越重连越慢甚至 503),再抛MEDIA_MSE_ERROR走原有重试路径发新请求。2.
components/player/video-player.tsx:MAX_RETRIES3 → 100原版播放稳定 30 秒会重置 retry baseline,所以这个数只约束真正无望的流,不会无限重试坏源。
为什么不在 C 端做转码
这些台是 H.264 + MP2 音频,浏览器 MSE 不认 MP2,前端已经用 minimp3 WASM 软解(
pcm-audio-player.ts),音频不是"没解",所以不是解码器缺失问题。实际验证过在服务端把音频转 AAC(
-c:v copy -c:a aac):仍然会卡,而 rtp2httpd 本身是零拷贝转发、不解析也不改写负载。所以问题定位在客户端播放管线的停读,不在转发层。验证
说明
改动只碰播放器前端两个文件,未改 C 代码、未改配置格式、未引入依赖。