aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/static
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-17 14:44:57 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-17 14:44:57 +0200
commit30980ba0994d3e99d41c5252555320d6cbb1f5a9 (patch)
treee23cfcc4c4eb53a2cc95359654835627495a5811 /packages/meshbay-hub/src/meshbay_hub/static
parent4134729543139f4934c4ec4e4c6a2cda0606bcdf (diff)
downloadmeshbay-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/meshbay-hub/src/meshbay_hub/static')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/video-player.js27
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(() => {