From b9248cfe2da65c58fc65c09855d609dce8a903a3 Mon Sep 17 00:00:00 2001 From: Astounds Date: Sun, 3 May 2026 13:45:00 -0500 Subject: [PATCH] fix: init Plyr before HLS manifest loads to avoid bare video flash Create Plyr instance immediately in start() so the styled player UI appears right away. Quality and audio controls are injected once the HLS manifest is ready, running doAdd() directly when player.ready is already true instead of waiting on the 'ready' event that already fired. --- youtube/static/js/plyr.hls.start.js | 215 +++++++++++++--------------- 1 file changed, 101 insertions(+), 114 deletions(-) diff --git a/youtube/static/js/plyr.hls.start.js b/youtube/static/js/plyr.hls.start.js index bc8ec23..69e24bd 100644 --- a/youtube/static/js/plyr.hls.start.js +++ b/youtube/static/js/plyr.hls.start.js @@ -150,7 +150,7 @@ * Create custom quality control in Plyr controls */ function addCustomQualityControl(player, qualityLabels) { - player.on('ready', () => { + function doAdd() { console.log('Adding custom quality control...'); const controls = player.elements.container.querySelector('.plyr__controls'); @@ -238,14 +238,21 @@ } console.log('Custom quality control added'); - }); + } + + // Run immediately if Plyr is already ready, otherwise wait + if (player.ready) { + doAdd(); + } else { + player.on('ready', doAdd); + } } /** * Create custom audio tracks control in Plyr controls */ function addCustomAudioTracksControl(player, hlsInstance) { - player.on('ready', () => { + function doAdd() { console.log('Adding custom audio tracks control...'); const controls = player.elements.container.querySelector('.plyr__controls'); @@ -397,117 +404,13 @@ }); console.log('Custom audio tracks control added'); - }); - } - - /** - * Initialize Plyr with HLS quality options - */ - function initPlyrWithQuality(hlsInstance) { - const video = document.getElementById('js-video-player'); - - if (!hlsInstance || !hlsInstance.levels || hlsInstance.levels.length === 0) { - console.error('HLS not ready'); - return; } - if (!video) { - console.error('Video element not found'); - return; - } - - console.log('HLS levels available:', hlsInstance.levels.length); - - const sortedLevels = [...hlsInstance.levels].sort((a, b) => b.height - a.height); - - const seenHeights = new Set(); - const uniqueLevels = []; - - sortedLevels.forEach((level) => { - if (!seenHeights.has(level.height)) { - seenHeights.add(level.height); - uniqueLevels.push(level); - } - }); - - const qualityLabels = ['auto']; - uniqueLevels.forEach((level) => { - const originalIndex = hlsInstance.levels.indexOf(level); - const label = level.height + 'p'; - if (!window.hlsQualityMap[label]) { - qualityLabels.push(label); - window.hlsQualityMap[label] = originalIndex; - } - }); - - console.log('Quality labels:', qualityLabels); - - const playerOptions = { - autoplay: autoplayActive, - disableContextMenu: false, - captions: { - active: captionsActive, - language: typeof data !== 'undefined' ? data.settings.subtitles_language : 'en', - }, - controls: [ - 'play-large', - 'play', - 'progress', - 'current-time', - 'duration', - 'mute', - 'volume', - 'captions', - 'settings', - 'pip', - 'airplay', - 'fullscreen', - ], - iconUrl: '/youtube.com/static/modules/plyr/plyr.svg', - blankVideo: '/youtube.com/static/modules/plyr/blank.webm', - debug: false, - storage: { enabled: false }, - previewThumbnails: { - enabled: typeof storyboard_url !== 'undefined' && storyboard_url !== null, - src: typeof storyboard_url !== 'undefined' && storyboard_url !== null ? [storyboard_url] : [], - }, - settings: ['captions', 'speed', 'loop'], - tooltips: { - controls: true, - }, - }; - - console.log('Creating Plyr...'); - - try { - plyrInstance = new Plyr(video, playerOptions); - console.log('Plyr instance created'); - - window.plyrInstance = plyrInstance; - - addCustomQualityControl(plyrInstance, qualityLabels); - addCustomAudioTracksControl(plyrInstance, hlsInstance); - - if (plyrInstance.eventListeners) { - plyrInstance.eventListeners.forEach(function(eventListener) { - if(eventListener.type === 'dblclick') { - eventListener.element.removeEventListener(eventListener.type, eventListener.callback, eventListener.options); - } - }); - } - - plyrInstance.started = false; - plyrInstance.once('playing', function(){this.started = true}); - - if (typeof data !== 'undefined' && data.time_start != 0) { - video.addEventListener('loadedmetadata', function() { - video.currentTime = data.time_start; - }); - } - - console.log('Plyr init complete'); - } catch (e) { - console.error('Failed to initialize Plyr:', e); + // Run immediately if Plyr is already ready, otherwise wait + if (player.ready) { + doAdd(); + } else { + player.on('ready', doAdd); } } @@ -522,14 +425,98 @@ return; } + // Initialize Plyr immediately so the player UI shows right away + // instead of a bare