From 8fe1c6dfbc4a6e0ff03f982b185f9be220a2adb4 Mon Sep 17 00:00:00 2001 From: Timo <6156589+Shik3i@users.noreply.github.com> Date: Thu, 2 Jul 2026 14:26:53 +0200 Subject: [PATCH] Fix laggy Disney+ time by preferring the live "time remaining" indicator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Disney+ throttles the scrubber slider's aria-valuenow, so it can lag real playback by several seconds (and its value snaps back when the control overlay reappears on pause). The player's "time remaining" indicator, however, updates live. getDisneyPlusUiTimeline() now captures any element whose class/testid mentions "remain", parses its clock text, and — when a reliable duration is known — derives current = duration - remaining and prefers it over the laggy slider value. Falls back to the previous behavior when no remaining indicator is present. Co-Authored-By: Claude Opus 4.8 --- extension/content.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/extension/content.js b/extension/content.js index c7cbb76..115f08f 100644 --- a/extension/content.js +++ b/extension/content.js @@ -144,6 +144,7 @@ const candidates = []; let best = null; let bestScore = -1; + let remainingSeconds = null; function considerTimeline(parsed, source, weight = 0) { if (!parsed) return; @@ -175,9 +176,24 @@ const parsed = parseTimelineText(text); considerTimeline(parsed, 'text', 100); textParts.push(text); + } + // Disney's scrubber aria-valuenow can lag several seconds behind + // real playback; a "time remaining" indicator updates live, so + // capture it and later derive current = duration - remaining. + const remClass = String(node.getAttribute?.('class') || '') + ' ' + String(node.getAttribute?.('data-testid') || ''); + if (/remain/i.test(remClass)) { + const remMatch = String(node.textContent || '').match(/\d{1,3}:\d{2}(?::\d{2})?/); + const rem = remMatch ? parseClockTime(remMatch[0]) : null; + if (Number.isFinite(rem) && rem >= 0) remainingSeconds = rem; } } + if (best && remainingSeconds !== null && best.duration > 0) { + const liveCurrent = best.duration - remainingSeconds; + if (liveCurrent >= 0 && liveCurrent <= best.duration + 5) { + considerTimeline({ current: Math.min(liveCurrent, best.duration), duration: best.duration }, 'time-remaining', 1000); + } + } considerTimeline(parseTimelineText(textParts.join(' ')), 'combined-text', 25); lastDisneyPlusTimelineCandidates = candidates .sort((a, b) => b.score - a.score)