Fix YouTube embed error 153 - add mute, origin, and enablejsapi params

- Add mute=1, enablejsapi=1, and origin params to YouTube embed URLs
- Fix applies at creation time (content route) and playback time (player)
- Existing YouTube content gets fixed params via fixYoutubeUrl() helper
- Also fixes content library preview iframe

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
ScreenTinker 2026-04-08 14:25:44 -05:00
parent 4ae7533b85
commit af371b9d89
3 changed files with 14 additions and 4 deletions

View file

@ -473,7 +473,7 @@ function showPreview(content) {
<button style="position:absolute;top:8px;right:8px;z-index:1;background:rgba(0,0,0,0.7);border:none;color:white;width:32px;height:32px;border-radius:50%;font-size:18px;cursor:pointer" id="closePreview">&times;</button>
<div style="max-width:80vw;max-height:80vh">
${isYoutube
? `<iframe src="${src}" style="width:80vw;height:45vw;max-height:80vh;display:block;border:none" allow="autoplay;encrypted-media" allowfullscreen></iframe>`
? `<iframe src="${(() => { try { const u = new URL(src); if (!u.searchParams.has('mute')) u.searchParams.set('mute','1'); if (!u.searchParams.has('enablejsapi')) u.searchParams.set('enablejsapi','1'); if (!u.searchParams.has('origin')) u.searchParams.set('origin', window.location.origin); return u.toString(); } catch { return src; } })()}" style="width:80vw;height:45vw;max-height:80vh;display:block;border:none" allow="autoplay;encrypted-media" allowfullscreen></iframe>`
: isVideo
? `<video src="${src}" controls autoplay style="max-width:80vw;max-height:80vh;display:block"></video>`
: `<img src="${src}" style="max-width:80vw;max-height:80vh;display:block">`

View file

@ -504,6 +504,16 @@
}
// ==================== Content Rendering ====================
function fixYoutubeUrl(url) {
try {
const u = new URL(url);
if (!u.searchParams.has('mute')) u.searchParams.set('mute', '1');
if (!u.searchParams.has('enablejsapi')) u.searchParams.set('enablejsapi', '1');
if (!u.searchParams.has('origin')) u.searchParams.set('origin', window.location.origin);
return u.toString();
} catch { return url; }
}
function renderContent(item) {
const container = document.getElementById('playerContainer');
container.style.display = 'block';
@ -522,7 +532,7 @@
// Fullscreen
if (isYoutube) {
const iframe = document.createElement('iframe');
iframe.src = src;
iframe.src = fixYoutubeUrl(src);
iframe.allow = 'autoplay; encrypted-media';
iframe.allowFullscreen = true;
iframe.style.cssText = 'width:100%;height:100%;border:none;background:#000';
@ -584,7 +594,7 @@
div.appendChild(iframe);
} else if (isYoutubeZone) {
const iframe = document.createElement('iframe');
iframe.src = src;
iframe.src = fixYoutubeUrl(src);
iframe.allow = 'autoplay; encrypted-media';
iframe.allowFullscreen = true;
iframe.style.cssText = 'width:100%;height:100%;border:none';

View file

@ -150,7 +150,7 @@ router.post('/youtube', (req, res) => {
if (!videoId) return res.status(400).json({ error: 'Invalid YouTube URL' });
const id = uuidv4();
const embedUrl = `https://www.youtube.com/embed/${videoId}?autoplay=1&controls=0&rel=0&modestbranding=1&loop=1&playlist=${videoId}`;
const embedUrl = `https://www.youtube.com/embed/${videoId}?autoplay=1&mute=1&controls=0&rel=0&modestbranding=1&loop=1&playlist=${videoId}&enablejsapi=1&origin=${encodeURIComponent(req.protocol + '://' + req.get('host'))}`;
const thumbnailUrl = `https://img.youtube.com/vi/${videoId}/hqdefault.jpg`;
const filename = name || `YouTube: ${videoId}`;