Play favorites from freshly resolved formats, not the page URL
Streaming a page URL makes /api/stream re-run yt-dlp on every request -- slow, and a 500 on some sites -- so the player and the reels feed now wait for App.videos.ensureFormats() when an item has no formats (favorites, or a card clicked before its hover-resolve landed) and play a real media URL with the extractor's headers, the same path a hovered card takes. Favorites' download does the same. The page URL survives only as a last resort when resolution yields nothing. Two things in the proxy kept this site broken either way: heavyfetish serves media from paths with a trailing slash (/get_file/.../11097_720p.mp4/), which missed every extension test in stream_video and sent even a resolved media URL down the yt-dlp branch -- a full extraction per request, including every seek. Its CDN (st17.heavyfetish.com) also serves a certificate that expired 2026-02-16, so the upstream fetch failed verification and returned 500. A browser can't play such a host at all, which is much of why this proxy exists, so impersonate_get() now retries once without verification, logs it, and remembers the host so the doomed handshake isn't repeated for every range request. STREAM_TLS_VERIFY_ONLY=1 restores the hard failure. Verified in headless Chrome against the real site: a favorite holding only the page URL now resolves, streams (206, video/mp4, duration 3167.8s, readyState 4, no error) and shows "720p mp4 | 480p mp4" in the quality menu. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QBDkEXP4htyXTCZUwMLphd
This commit is contained in:
@@ -331,6 +331,21 @@ App.feed = App.feed || {};
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// A slide whose formats haven't been resolved yet carries only a page
|
||||
// URL, and handing that to /api/stream makes the backend re-run yt-dlp
|
||||
// per request (slow, and a hard failure on some sites). Resolve once,
|
||||
// then load for real -- `_awaitingFormats` keeps a failed resolve from
|
||||
// looping, so we still fall back to the page URL as a last resort.
|
||||
const meta = videoData && (videoData.meta || videoData);
|
||||
const hasFormats = !!(meta && Array.isArray(meta.formats) && meta.formats.length);
|
||||
if (!hasFormats && !slide._awaitingFormats && App.videos && typeof App.videos.ensureFormats === 'function') {
|
||||
slide._awaitingFormats = true;
|
||||
App.videos.ensureFormats(videoData).then(() => {
|
||||
if (slide._videoData === videoData) loadSlideSource(slide, videoData, autoplay);
|
||||
});
|
||||
return;
|
||||
}
|
||||
slide.classList.add('is-loaded');
|
||||
|
||||
const resolved = slide._formatOverride
|
||||
|
||||
Reference in New Issue
Block a user