mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 16:02:26 +00:00
Merge pull request #1130 from PR0M3TH3AN/codex/create-documentation-for-playback-fallback
Add playback fallback documentation and README link
This commit is contained in:
2 files changed
+95
No files matched your search
@@ -53,6 +53,7 @@ Hosted URLs remain the preferred playback path, and you can still add a magnet o
|
||||
2. **WebTorrent fallback**: If the URL probe fails or returns an error status, bitvid falls back to WebTorrent using the raw magnet. The helpers append HTTPS `ws=`/`xs=` hints so peers seed quickly.
|
||||
3. **Safety checks**: Magnets are decoded with `safeDecodeMagnet()` and normalized via `normalizeAndAugmentMagnet()` before reaching WebTorrent. Trackers remain WSS-only to satisfy browser constraints.
|
||||
4. **Operator playbook**: If a deployment causes playback regressions, flip the relevant feature flags back to their default values in `js/constants.js` and redeploy. Capture the rollback steps in AGENTS.md and the PR description so the Main channel stays stable.
|
||||
5. **Deep dive**: See [`docs/playback-fallback.md`](docs/playback-fallback.md) for the call flow into `playbackService`, magnet normalization details, and fallback hand-off points.
|
||||
|
||||
### Watch history & view counts
|
||||
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
# URL-first playback fallback orchestration
|
||||
|
||||
This document explains how `bitvidApp.playVideoWithFallback` in `js/app.js` coordinates hosted URL playback first and falls back to WebTorrent when needed. It also covers the supporting helpers in `js/services/playbackService.js`, `js/playbackUtils.js`, and `js/magnetUtils.js`, including how tracker lists and `ws=`/`xs=` hints are applied.
|
||||
|
||||
## High-level flow
|
||||
|
||||
1. `bitvidApp.playVideoWithFallback({ url, magnet })` trims inputs, ensures the video modal is ready, and constructs a playback session via `playbackService.createSession(...)`.
|
||||
2. The session (from `js/services/playbackService.js`) derives a canonical magnet payload using `deriveTorrentPlaybackConfig` (from `js/playbackUtils.js`).
|
||||
3. Playback starts with the hosted URL when `URL_FIRST_ENABLED` is true and a URL is available; otherwise, it goes directly to torrent playback.
|
||||
4. If URL playback stalls or errors, the session triggers `playViaWebTorrent` with the normalized magnet and optional web seed hints.
|
||||
|
||||
## Call flow into playbackService
|
||||
|
||||
`bitvidApp.playVideoWithFallback` performs UI preparation and delegates the decision-making to a `PlaybackSession`:
|
||||
|
||||
- **Session setup**
|
||||
- `playbackService.createSession({ url, magnet, videoElement, probeUrl, playViaWebTorrent, ... })`
|
||||
- The session captures `url`, `magnet`, and a request signature to de-duplicate duplicate calls.
|
||||
- **Hosted URL probe**
|
||||
- `PlaybackSession.execute()` calls `probeUrl(url)` to check availability and decides whether to attempt direct playback.
|
||||
- **Hosted URL playback**
|
||||
- On a successful probe, the session assigns `video.src = url` and calls `video.play()`.
|
||||
- It registers watchdogs (`registerUrlPlaybackWatchdogs`) to detect stalls, errors, or aborts.
|
||||
- **Fallback to WebTorrent**
|
||||
- If watchdogs trigger or direct playback fails, `PlaybackSession` calls `playViaWebTorrent(magnet, { fallbackMagnet, urlList })`.
|
||||
- `urlList` includes the hosted URL (if present) so it becomes a WebTorrent web seed.
|
||||
|
||||
## Magnet helpers and normalization
|
||||
|
||||
`playbackService` doesn’t manipulate magnets directly. It relies on `deriveTorrentPlaybackConfig` in `js/playbackUtils.js`, which does the following:
|
||||
|
||||
- Calls `safeDecodeMagnet()` from `js/magnetUtils.js` so URL-encoded magnets become raw `magnet:?xt=urn:btih:...` strings.
|
||||
- Accepts bare info hashes and promotes them to full magnet URIs when needed.
|
||||
- Runs `normalizeAndAugmentMagnet()` (from `js/magnetUtils.js`) to:
|
||||
- Append `ws=` web seed hints when a hosted URL is present.
|
||||
- Append `xs=` torrent hints when supplied.
|
||||
- Ensure WSS-only tracker URLs are present.
|
||||
|
||||
The result is a canonical magnet used by WebTorrent, plus an optional `fallbackMagnet` that preserves the original raw input if normalization changed it.
|
||||
|
||||
## Tracker lists, ws/xs hints, and constants
|
||||
|
||||
Tracker and hint behavior is centralized in `js/constants.js` and `js/magnetUtils.js`:
|
||||
|
||||
- `WSS_TRACKERS` in `js/constants.js` is the canonical browser-safe tracker list. `normalizeAndAugmentMagnet()` merges this list into the magnet if trackers are missing.
|
||||
- `normalizeAndAugmentMagnet()` also applies `ws=` web seed hints (from the hosted URL) and `xs=` torrent hints (from user input), enforcing HTTPS when appropriate.
|
||||
- `URL_FIRST_ENABLED` (also in `js/constants.js`) controls whether the hosted URL probe is attempted before torrent fallback.
|
||||
|
||||
## Failure detection and hand-off points
|
||||
|
||||
The fallback hand-off happens in these places inside `PlaybackSession.execute()`:
|
||||
|
||||
1. **URL probe fails**: `probeUrl(url)` reports a bad outcome → session skips direct playback and goes straight to WebTorrent.
|
||||
2. **Playback errors**: `video.play()` throws or fires `error` → session triggers the fallback.
|
||||
3. **Playback stalls**: the watchdog timer (`registerUrlPlaybackWatchdogs`) detects `stalled`, `abort`, or no progress → session triggers the fallback.
|
||||
4. **Autoplay blocked**: the browser blocks autoplay → session waits for a user gesture, re-enables watchdogs, and only falls back if playback still fails.
|
||||
|
||||
## Sequence diagram
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant App as bitvidApp (js/app.js)
|
||||
participant Service as PlaybackService (js/services/playbackService.js)
|
||||
participant Session as PlaybackSession
|
||||
participant Video as HTMLVideoElement
|
||||
participant Magnet as magnetUtils/playbackUtils
|
||||
|
||||
App->>Service: createSession({ url, magnet, videoElement, ... })
|
||||
Service->>Session: new PlaybackSession(...)
|
||||
Session->>Magnet: deriveTorrentPlaybackConfig()
|
||||
Magnet-->>Session: normalized magnet + fallbackMagnet
|
||||
|
||||
Session->>App: showModalWithPoster()
|
||||
Session->>App: probeUrl(url)
|
||||
alt URL probe ok + URL_FIRST_ENABLED
|
||||
Session->>Video: src=url; play()
|
||||
Session->>Session: registerUrlPlaybackWatchdogs()
|
||||
alt hosted playback succeeds
|
||||
Session-->>App: sourcechange("url")
|
||||
else watchdog/error triggers
|
||||
Session->>App: playViaWebTorrent(magnet, { urlList })
|
||||
Session-->>App: sourcechange("torrent")
|
||||
end
|
||||
else URL probe fails or URL-first disabled
|
||||
Session->>App: playViaWebTorrent(magnet, { urlList })
|
||||
Session-->>App: sourcechange("torrent")
|
||||
end
|
||||
```
|
||||
|
||||
## Implementation notes
|
||||
|
||||
- The playback session is responsible for cleanup and emits events (`status`, `sourcechange`, `error`, `finished`) that `bitvidApp` listens to for UI updates.
|
||||
- `bitvidApp.playVideoWithFallback` keeps the current video card and modal state in sync with the normalized magnet values so copy actions and stats reflect the actual playback payload.
|
||||
|
||||
Reference in new issue
Block a user