Some channels hand back the media URL itself as an item's url. Since the favorites fix, opening one of those sent it to /api/resolve first, so yt-dlp fetched the media just to report the URL we already had. On a signed link (`?secure=<ts>-<token>`) that is a second request against something that may be single-use or IP-bound, and the request that matters -- the playback fetch -- is then refused. Such URLs now play directly, with no resolve round trip, as they did before. Alongside that, three things that make expiry survivable: /api/stream, after its existing referer-less retry, now retries a 403 completely bare (Range only). Signed CDN links are routinely served to a plain browser request and refused when it carries extras -- a `Sec-Fetch-Mode: navigate` on a media subresource, say, which is what yt-dlp's generic extractor hands back and no real player would send. When every source fails, the player re-resolves once and retries instead of giving up, since the likeliest cause is that signed URLs went stale in a long-open tab rather than the video being gone. A manual quality pick is dropped for that retry, as it names one of the URLs that just failed. Favorites stored by older versions still carry a `meta` blob of resolved formats, long expired; it's now stripped on read so nothing can reach for one. Verified: a favorite whose url is a .mp4 plays with zero /api/resolve calls, straight from that URL; playback, prefetch, feed paging, HUD, rotation, momentum and the version check all still pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QBDkEXP4htyXTCZUwMLphd
47 KiB
47 KiB