mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-11-03 03:12:31 +00:00
docs: video-liveness plan (speed, playability probe, multi-source)
Audited the card liveness/health system. Policy (cardSourceVisibility) is already correct — hides only when neither CDN nor WebTorrent is healthy, un-hides when WebTorrent flips green. Documents the real gaps (slow probes; opaque HEAD no-cors inaccuracy for cross-origin NIP-71 CDNs; single-source adapter dropping extra imeta) and a 3-phase plan: multi-source capture, video-element playability probe across sources, and speed tuning. Adds docs/video-liveness-plan.md + expands pre-launch TODO #5. Planning only. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
f760abde3d
commit
5e2b22156f
2 files changed
+90
-5
No files matched your search
@@ -0,0 +1,73 @@
|
||||
# Video Liveness / Card Health — Dev Plan
|
||||
|
||||
Status: **planned** (investigated; not started). Branch: `unstable`.
|
||||
|
||||
## Goal
|
||||
Cards should only render videos that can actually play, decide fast, support
|
||||
multiple source links (fall back if one is down), and never show two of the same
|
||||
video (handled separately by cross-ecosystem dedup). Prefer CDN; if CDN is dead
|
||||
but a WebTorrent source is live, keep the card.
|
||||
|
||||
## What already works (don't rebuild)
|
||||
- **Hide/show policy is correct** (`js/utils/cardSourceVisibility.js`): a card
|
||||
hides only when **neither** CDN (`urlHealthState`) **nor** WebTorrent
|
||||
(`streamHealthState`) is healthy (and neither is pending); it un-hides the
|
||||
moment WebTorrent flips `healthy`. This already matches "no CDN → block; if a
|
||||
webtorrent flips green → bring it back."
|
||||
- Owner's own videos bypass hiding.
|
||||
|
||||
## The real problems (diagnosis)
|
||||
1. **Too slow.** `URL_PROBE_TIMEOUT_MS = 8s` (+ a retry), WebTorrent
|
||||
`PROBE_TIMEOUT_MS = 20s`. While a probe is *pending*, the card is **shown**
|
||||
(pending ≠ hidden). So unplayable videos sit visible for many seconds before
|
||||
being hidden. → tune timeouts + concurrency for a faster verdict.
|
||||
2. **Probe accuracy.** The CDN check races a `HEAD {mode:"no-cors"}` which is
|
||||
**opaque** (status unreadable) for cross-origin hosts (most NIP-71 CDNs like
|
||||
`relay.towardsliberty.com`). Opaque without `confirmPlayable` → `unknown` (not
|
||||
healthy). Whether a card shows then hinges on timing/streamState. Net: foreign
|
||||
CDNs are judged unreliably. → use the **video-element probe** (`confirmPlayable`,
|
||||
actually loads the media) as the source of truth for the card verdict.
|
||||
3. **Single source only.** The ingest adapter keeps ONE `url` (the primary imeta
|
||||
variant) and drops the rest. NIP-71 events can list **multiple imeta** (mirrors
|
||||
/ alternate media). Example: Walker/THE Bitcoin Podcast event has a `video/mp4`
|
||||
imeta AND an `audio/mpeg` imeta; other events may list multiple video mirrors.
|
||||
→ capture all playable sources and fall back across them.
|
||||
|
||||
## Plan
|
||||
|
||||
### Phase 1 — Multi-source capture (adapter + video model)
|
||||
- `buildVideoFromNip71Event` (and the 30078 path where applicable) should expose a
|
||||
`sources` list: every imeta `url` whose `m` is a video type (and the magnet),
|
||||
in order, each with `{ url, mimeType, sha256, dim, duration }`. Keep the primary
|
||||
`url`/`magnet` for back-compat; add `sources` for fallback.
|
||||
- Skip non-video media (e.g. `audio/mpeg`) for the *video* player, but we may keep
|
||||
audio as a separate affordance later (out of scope).
|
||||
|
||||
### Phase 2 — Liveness uses real playability across sources
|
||||
- The card URL probe should try sources **in order** via the video-element probe
|
||||
(`confirmPlayable`); `healthy` if ANY source loads; `offline` only if ALL fail.
|
||||
- Cache per-source results (already have a probe cache) so scrolling doesn't
|
||||
re-probe.
|
||||
- Player playback should consume the same ordered `sources` so the one that
|
||||
probed healthy is what plays (and can fail over at play time too).
|
||||
|
||||
### Phase 3 — Speed
|
||||
- Lower `URL_PROBE_TIMEOUT_MS` (8s → ~3–4s) and the video-element probe timeout;
|
||||
keep one retry only for `timeout` (not `error`). Consider bumping URL-probe
|
||||
concurrency (it's cheap vs WebTorrent swarm joins).
|
||||
- WebTorrent `PROBE_TIMEOUT_MS` (20s): keep generous (swarm joins are slow) but
|
||||
ensure it runs in parallel and never blocks the CDN verdict.
|
||||
- DECISION NEEDED: **show-pending (current) vs hide-until-verified.** Showing
|
||||
pending means a brief flash of soon-to-be-hidden dead cards; hide-until-verified
|
||||
means good cards pop in after the probe. Recommend: keep show-pending for cards
|
||||
with a *bitvid-native/whitelisted* source (fast/trusted), but **hide-until-verified
|
||||
for foreign/ingested** videos (so unplayable strangers never flash in).
|
||||
|
||||
## Reuse map
|
||||
- `js/ui/urlHealthController.js` (probeUrl / probeUrlWithVideoElement) — make
|
||||
it iterate sources + prefer the video-element verdict.
|
||||
- `js/gridHealth.js` (WebTorrent swarm probe) — timing only.
|
||||
- `js/utils/cardSourceVisibility.js` — policy already correct; no change expected.
|
||||
- `js/nostr/nip71IngestAdapter.js` — add `sources`.
|
||||
- `js/constants.js` — `URL_PROBE_TIMEOUT_MS`, probe concurrency.
|
||||
- Player/playback service — consume `sources` for fail-over.
|
||||
@@ -106,11 +106,23 @@ tests → `npm run build` + `npm run test:unit` green → commit + push.
|
||||
double-counting, and resilience to dead relays (now that feed defaults are
|
||||
reserved, ensure view reads/writes use a sane relay set too).
|
||||
|
||||
### 5. Card-hide / video-liveness check
|
||||
- [ ] Audit the card-hide system that gates a card on a video-liveness probe
|
||||
(`gridHealth.js`, probe concurrency now 4). Confirm: dead URL/magnet hides the
|
||||
card correctly, a live video is never falsely hidden, and the probe can't
|
||||
stampede connections (regression risk from the freeze fix).
|
||||
### 5. Card-hide / video-liveness check — full plan in docs/video-liveness-plan.md
|
||||
Audited (2026-06-23). Finding: the hide/show **policy is already correct**
|
||||
(`cardSourceVisibility.js` hides only when neither CDN nor WebTorrent is healthy;
|
||||
un-hides when WebTorrent flips green). The real gaps:
|
||||
- [ ] **Speed**: `URL_PROBE_TIMEOUT_MS=8s` (+retry) and WebTorrent probe 20s mean
|
||||
unplayable cards stay *visible* (pending isn't hidden) for seconds. Tune
|
||||
timeouts + concurrency for a faster verdict.
|
||||
- [ ] **Probe accuracy**: the CDN check races an opaque `HEAD no-cors` (status
|
||||
unreadable for cross-origin NIP-71 CDNs). Use the **video-element probe**
|
||||
(`confirmPlayable`, actually loads media) as the card verdict.
|
||||
- [ ] **Multi-source**: ingest adapter keeps ONE url; NIP-71 events can list
|
||||
multiple imeta (mirrors / alternate media). Capture all video sources +
|
||||
magnet; probe/play them in order; healthy if ANY plays, offline only if ALL
|
||||
fail. (Example: Walker/THE Bitcoin Podcast event — mp4 + mp3 imeta.)
|
||||
- [ ] **Decision**: show-pending (current) vs hide-until-verified for foreign
|
||||
ingested videos (so unplayable strangers never flash in). Recommend
|
||||
hide-until-verified for foreign, show-pending for bitvid-native.
|
||||
|
||||
## Open — medium priority
|
||||
|
||||
|
||||
Reference in new issue
Block a user