Files
ytplayer/docs/related-video-recovery.md

2.4 KiB

Related-video recovery

The old Now Playing related loader called /api/search with the complete title. That endpoint follows up to 14 InnerTube pages to collect 200 results, then uses resilient yt-dlp if necessary. Related displayed only eight cards. It had no alternate query or catalog fallback, silently caught failures, and hid its panel. It also read mutable current after awaiting the request, allowing a previous song's response to populate the next song's recommendations.

A read-only production probe (/api/search?q=Rock Medley&refresh=1) returned 200 results successfully during this investigation. No persistent IP/account/region block was reproduced, and no privileged production logs or credentials were used. The exact intermittent upstream YouTube rejection cannot be established from that successful probe. The failure handling and request coupling above are verified directly in the previous code and reproduced in tests.

The new /api/related endpoint first reads one InnerTube watch-next response, including compact and modern lockup video cards. A local real request for wZzRoXymOUU parsed 20 recommendations. Failures/empty results fall back to bounded single-page title/channel searches, then the existing resilient yt-dlp search path, then videos already known to the server. It excludes the current song, deduplicates, returns eight cards, shares in-flight work and caches successful results. Failed responses are not cached; Retry bypasses the success cache. The YouTube work has an 18-second total budget with per-operation timeouts. The existing SEARCH_INNERTUBE=0 switch still disables InnerTube.

Every new discovery goes through the existing metadata catalog/thumbnail collector. A metadata persistence failure cannot hide otherwise playable cards. Related's client snapshots the song and ignores superseded responses. When all sources are unavailable, its panel stays visible with a friendly message and Retry, rather than disappearing. Catalog fallback is explicitly labelled.

Validation: frontend loader tests cover filtering, errors, retry refresh and stale responses. Server tests cover renderer parsing, next/search/catalog fallbacks, metadata collection, cache/in-flight deduplication, deadline exhaustion, and route validation. Browser tests in both themes, Chromium and WebKit at 390 px, exercise 503 → Retry → results and assert that the section rail retains its parent.

No changes to the Glass section rail; no push or deployment.