playback: fail over across hosted mirrors before dropping to P2P (#5)

The liveness probe already tries all of a video's sources, but actual playback
only ever tried the single primary URL and then fell straight to WebTorrent. Now
playback fails over across hosted mirrors first.

- PlaybackSession builds an ordered, de-duped hostedSourceCandidates (primary URL
  first, then the video's imeta `sources`; accepts string or {url} entries).
- attemptHostedPlayback takes a candidateUrl; the url-first execution loop tries
  each candidate and advances to the next mirror on probe-fail/stall/timeout,
  cleaning up watchdogs + resetting the <video> between candidates, only calling
  WebTorrent after every hosted mirror fails.
- `sources` plumbed coordinator -> strategy -> session. Single-source videos
  (no `sources`) behave exactly as before.

Tests: tests/services/playbackService_multisource.test.mjs (candidate
construction; the full async fail-over flow is covered by the existing
playbackService_order suite in CI — that mock-timers harness doesn't run in this
sandbox). ROLLBACK: revert the loop to the single attemptHostedPlayback() call
and drop the sources plumbing.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
thePR0M3TH3ANandClaude Opus 4.8 committed 2026-06-24 13:30:30 -04:00
1 parent c967789257
commit 0a37e625bb
5 files changed
+171 -30

No files matched your search

+2
View File
@@ -197,6 +197,8 @@ export class PlaybackStrategyService {
const session = this.playbackService.createSession({
url: sanitizedUrl,
magnet: trimmedMagnet,
// Hosted mirrors to fail over to when the primary URL dies mid-load.
sources: Array.isArray(options.sources) ? options.sources : [],
requestSignature,
videoElement: modalVideoEl,
waitForCleanup: context.waitForCleanup,