Sync Disney+ via the page media player API (precise time + seek)

Disney+'s <video> is blob-relative (unusable as an absolute clock) and its
scrubber aria-value freezes during playback, so DOM scraping lagged and the
+/-10s button seek could neither reach far targets nor land precisely. The
real player hangs off the <disney-web-player> custom element as
`.mediaPlayer`, exposing seek(ms) and timeline.info (playhead/duration ms).

Since the isolated content world can't read that page object, route it
through the existing MAIN-world page-API bridge (as Netflix already does):

- page-api-seek-overrides.js: register a 'disney' provider.
- background.js installPageApiSeekBridge: seek Disney via mediaPlayer.seek(),
  and post the exact playhead/duration (seconds) to the content world every
  250ms. Both are gated on provider === 'disney'; Netflix path unchanged.
- content.js: cache the pushed playhead, prefer it in getDisneyPlusTimeline
  (DOM scraping stays as fallback), and check the page-API seek first in
  seekVideo. Outcome is identical for Netflix and generic sites.

Verified live on Disney+: reported time matches the player exactly and
seek lands within ~1s of the target.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Timo
2026-07-02 14:56:02 +02:00
parent 236da46f5d
commit 076157fef1
4 changed files with 90 additions and 24 deletions
+1
View File
@@ -96,6 +96,7 @@ function loadTimelineFns(hostname, document = makeDocument()) {
'let lastKnownDisneyPlusStart = 0;',
'let lastDisneyPlusUiCurrent = null;',
'let lastDisneyPlusNativeAtUi = null;',
'let disneyPageApiTime = null;',
extractFunction('scanShadowDom', source),
extractFunction('querySelectorAllShadow', source),
extractFunction('hostMatchesUrl', source),