diff options
| author | Astounds <kirito@disroot.org> | 2026-03-27 19:22:12 -0500 |
|---|---|---|
| committer | Astounds <kirito@disroot.org> | 2026-03-27 19:22:12 -0500 |
| commit | 56ecd6cb1b461bd3622c669936050fa7e4d83542 (patch) | |
| tree | a67dc3b8dc75ea20a00e25162949626bd1c6f2a8 /youtube/static/js/common.js | |
| parent | f629565e77ae7178950fceaac7ba650b97bd4c51 (diff) | |
| download | yt-local-56ecd6cb1b461bd3622c669936050fa7e4d83542.tar.lz yt-local-56ecd6cb1b461bd3622c669936050fa7e4d83542.tar.xz yt-local-56ecd6cb1b461bd3622c669936050fa7e4d83542.zip | |
fix: use YouTube-provided thumbnail URLs instead of hardcoded hq720.jpg
Videos without hq720.jpg thumbnails caused mass 404 errors.
Now preserves the actual thumbnail URL from YouTube's API response,
falls back to hqdefault.jpg only when no thumbnail is provided.
Also picks highest quality thumbnail from API (thumbnails[-1])
and adds progressive fallback for subscription/download functions.
Diffstat (limited to 'youtube/static/js/common.js')
| -rw-r--r-- | youtube/static/js/common.js | 33 |
1 files changed, 15 insertions, 18 deletions
diff --git a/youtube/static/js/common.js b/youtube/static/js/common.js index bcd1539..ac4413b 100644 --- a/youtube/static/js/common.js +++ b/youtube/static/js/common.js @@ -121,11 +121,12 @@ window.addEventListener('DOMContentLoaded', function() { * Priority: hq720.jpg -> sddefault.jpg -> hqdefault.jpg -> mqdefault.jpg -> default.jpg */ function thumbnail_fallback(img) { - const src = img.src || img.dataset.src; + // Once src is set (image was loaded or attempted), always work with src + const src = img.src; if (!src) return; // Handle YouTube video thumbnails - if (src.includes('/i.ytimg.com/')) { + if (src.includes('/i.ytimg.com/') || src.includes('/i.ytimg.com%2F')) { // Extract video ID from URL const match = src.match(/\/vi\/([^/]+)/); if (!match) return; @@ -138,36 +139,32 @@ function thumbnail_fallback(img) { 'hq720.jpg', 'sddefault.jpg', 'hqdefault.jpg', - 'mqdefault.jpg', - 'default.jpg' ]; // Find current quality and try next fallback for (let i = 0; i < fallbacks.length; i++) { if (src.includes(fallbacks[i])) { - // Try next quality if (i < fallbacks.length - 1) { - const newSrc = imgPrefix + 'https://i.ytimg.com/vi/' + videoId + '/' + fallbacks[i + 1]; - if (img.dataset.src) { - img.dataset.src = newSrc; - } else { - img.src = newSrc; - } + img.src = imgPrefix + 'https://i.ytimg.com/vi/' + videoId + '/' + fallbacks[i + 1]; + } else { + // Last fallback failed, stop retrying + img.onerror = null; } - break; + return; } } + // Unknown quality format, stop retrying + img.onerror = null; } // Handle YouTube channel avatars (ggpht.com) else if (src.includes('ggpht.com') || src.includes('yt3.ggpht.com')) { - // Try to increase avatar size (s88 -> s240) const newSrc = src.replace(/=s\d+-c-k/, '=s240-c-k-c0x00ffffff-no-rj'); if (newSrc !== src) { - if (img.dataset.src) { - img.dataset.src = newSrc; - } else { - img.src = newSrc; - } + img.src = newSrc; + } else { + img.onerror = null; } + } else { + img.onerror = null; } } |
