diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-09-17 14:44:57 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-09-17 14:44:57 +0200 |
| commit | 30980ba0994d3e99d41c5252555320d6cbb1f5a9 (patch) | |
| tree | e23cfcc4c4eb53a2cc95359654835627495a5811 /packages | |
| parent | 4134729543139f4934c4ec4e4c6a2cda0606bcdf (diff) | |
| download | meshbay-30980ba0994d3e99d41c5252555320d6cbb1f5a9.tar.gz | |
fix(hub): sample activeCues, the number that decides whether a subtitle shows
Attach-time state — one track, showing, cues parsed — was all correct while
nothing appeared on screen, so it was measuring the wrong thing. A re-render
can replace the <track> and reset a mode nothing sets again, and a cue list
that does not cover the playhead looks identical to one that does.
The probe samples activeCues for ten seconds alongside the playhead, the mode,
and the cue that ought to be on screen at that instant, so "no cue is active"
and "a cue is active and is not painted" stop being the same observation.
Verified beforehand that the mechanism itself is sound: a real Chrome driven
over CDP, fed through MediaSource with timestampOffset 2690 and given a track
appended after playback started, reports activeCues 1 on the cue bracketing
the playhead.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UGY17EPph5LsLzePPXhUVc
Diffstat (limited to 'packages')
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/static/video-player.js | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/video-player.js b/packages/meshbay-hub/src/meshbay_hub/static/video-player.js index 596a848..3bb9124 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/video-player.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/video-player.js @@ -1159,6 +1159,33 @@ function VideoPlayer({ entry, transportRef, gekRef, onClose, onDownload }) { 'mode =', v.textTracks[0] && v.textTracks[0].mode, 'cues =', v.textTracks[0] && v.textTracks[0].cues ? v.textTracks[0].cues.length : 'none'); + if (!subtitleUrl) return; + // The state above is a single instant, and every part of it can be right + // there and wrong a second later: a re-render can replace the <track>, + // which resets the mode nothing would set again. What decides whether a + // subtitle is on screen is `activeCues`, and that is the one number no + // log has ever carried. Sampled for ten seconds, with the cue that ought + // to be showing at this instant, so "none active" and "active but not + // painted" stop being the same observation. + let n = 0; + const probe = setInterval(() => { + const tt = v.textTracks[0]; + if (!tt) { console.log('[MeshBay] subtitle probe: the track is gone'); return; } + const cues = tt.cues ? Array.from(tt.cues) : []; + const now = v.currentTime; + const should = cues.find((c) => c.startTime <= now && c.endTime >= now); + console.log('[MeshBay] subtitle probe', ++n, + 't =', now.toFixed(1), 'mode =', tt.mode, + 'cues =', cues.length, + 'active =', tt.activeCues ? tt.activeCues.length : 'null', + 'due here =', should ? `[${should.startTime.toFixed(1)}-` + + `${should.endTime.toFixed(1)}] ${should.text.slice(0, 40)}` : 'none', + 'first/last =', cues.length + ? `${cues[0].startTime.toFixed(1)}..${cues[cues.length - 1].endTime.toFixed(1)}` + : '-'); + if (n >= 5) clearInterval(probe); + }, 2000); + return () => clearInterval(probe); }, [subtitleUrl]); useEffect(() => { |