mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
Makes the card liveness-visibility behavior switchable so it can be A/B feel-tested, and probes ahead of the scroll for a snappier result. - CARD_LIVENESS_POLICY (config/instance-config.js): "show-pending" (default, unchanged) | "hide-foreign" (foreign/ingested cards hidden until a source verifies; native cards stay show-pending) | "hide-all". Owner's own cards are always visible. Flip live for testing without a rebuild: window.__BITVID_CARD_LIVENESS_POLICY__ = "hide-foreign" then refresh/scroll. Implemented via a data-foreign provenance flag on the card + getCardLivenessPolicy() in cardSourceVisibility.js. - LIVENESS_PROBE_PREFETCH_MARGIN (default 600px): both liveness probes were already viewport-gated (IntersectionObserver, on-screen-first, WebTorrent priority-queued + concurrency-capped); this expands their rootMargin so cards just below the fold verify before the user reaches them. - Tests: three policy scenarios in tests/video-card-source-visibility.test.mjs; also un-broke 3 pre-existing VideoCard tests by adding the missing IntersectionObserver JSDOM stub. Co-Authored-By: Claude Opus 4.8 <[email protected]>
4.3 KiB
4.3 KiB
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 flipshealthy. This already matches "no CDN → block; if a webtorrent flips green → bring it back." - Owner's own videos bypass hiding.
The real problems (diagnosis)
- Too slow.
URL_PROBE_TIMEOUT_MS = 8s(+ a retry), WebTorrentPROBE_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. - Probe accuracy. The CDN check races a
HEAD {mode:"no-cors"}which is opaque (status unreadable) for cross-origin hosts (most NIP-71 CDNs likerelay.towardsliberty.com). Opaque withoutconfirmPlayable→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. - 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 avideo/mp4imeta AND anaudio/mpegimeta; 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 asourceslist: every imetaurlwhosemis a video type (and the magnet), in order, each with{ url, mimeType, sha256, dim, duration }. Keep the primaryurl/magnetfor back-compat; addsourcesfor 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);healthyif ANY source loads;offlineonly 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
sourcesso 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 fortimeout(noterror). 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 (2026-06-24): made config-driven for live A/B testing instead of
hard-coding one policy.
CARD_LIVENESS_POLICY=show-pending(default) |hide-foreign|hide-all, flippable live viawindow.__BITVID_CARD_LIVENESS_POLICY__. Recommendation stands:hide-foreign(native = show-pending, foreign/ingested = hidden-until-verified). Also added a configurable probe prefetch margin (LIVENESS_PROBE_PREFETCH_MARGIN, default 600px) so cards verify before they scroll into view. Pick the final default after feel-testing.
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— addsources.js/constants.js—URL_PROBE_TIMEOUT_MS, probe concurrency.- Player/playback service — consume
sourcesfor fail-over.