From 9b941e5a77dbfcbb17c6c7705ea8d1059c953384 Mon Sep 17 00:00:00 2001 From: CodeDevMLH <145071728+CodeDevMLH@users.noreply.github.com> Date: Fri, 6 Mar 2026 01:23:49 +0100 Subject: [PATCH] test again --- .../Web/mediaBarEnhanced.js | 42 ++++++++++++++++--- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/Jellyfin.Plugin.MediaBarEnhanced/Web/mediaBarEnhanced.js b/Jellyfin.Plugin.MediaBarEnhanced/Web/mediaBarEnhanced.js index a71c61b..42e0eab 100644 --- a/Jellyfin.Plugin.MediaBarEnhanced/Web/mediaBarEnhanced.js +++ b/Jellyfin.Plugin.MediaBarEnhanced/Web/mediaBarEnhanced.js @@ -1782,15 +1782,44 @@ const SlideCreator = { } catch(e) { /* cross-origin access may fail on some iOS versions */ } }; - // Listen for YouTube state changes (e.g. video ended → advance slide) + // YouTube won't send onStateChange events unless we explicitly subscribe. + // The IFrame API does this automatically; we must do it manually for plain iframes. + const subscribeToYtEvents = () => { + try { + // Step 1: Announce we're listening + ytIframe.contentWindow?.postMessage( + JSON.stringify({ event: 'listening' }), + 'https://www.youtube-nocookie.com' + ); + // Step 2: Subscribe to state change events + ytIframe.contentWindow?.postMessage( + JSON.stringify({ event: 'command', func: 'addEventListener', args: ['onStateChange'] }), + 'https://www.youtube-nocookie.com' + ); + } catch(e) {} + }; + + // Subscribe when iframe has finished loading + ytIframe.addEventListener('load', subscribeToYtEvents); + + // Listen for YouTube state changes (video ended → advance slide) const handleYtMessage = (event) => { if (!event.origin.includes('youtube')) return; try { const data = typeof event.data === 'string' ? JSON.parse(event.data) : event.data; - if (data.event === 'onStateChange' && data.info === 0) { // 0 = YT.PlayerState.ENDED - const slide = document.querySelector(`.slide[data-item-id="${itemId}"]`); - if (slide && slide.classList.contains('active')) { - SlideshowManager.nextSlide(); + + // Player is ready — re-subscribe in case the first attempt was too early + if (data.event === 'onReady') { + subscribeToYtEvents(); + } + + if (data.event === 'onStateChange') { + console.log(`🍎 Safari YT state: ${data.info} for ${itemId}`); + if (data.info === 0) { // 0 = ENDED + const slide = document.querySelector(`.slide[data-item-id="${itemId}"]`); + if (slide && slide.classList.contains('active')) { + SlideshowManager.nextSlide(); + } } } } catch(e) {} @@ -2620,9 +2649,10 @@ const SlideshowManager = { } // Check if playback successfully started, otherwise fallback to muted + // (Only for real YT.Player instances — Safari stub's getPlayerState() always returns 1) setTimeout(() => { if (!currentSlide.classList.contains('active')) return; - if (player.getPlayerState && + if (player.getPlayerState && typeof YT !== 'undefined' && player.getPlayerState() !== YT.PlayerState.PLAYING && player.getPlayerState() !== YT.PlayerState.BUFFERING) { console.log("YouTube loadVideoById didn't start playback, retrying muted...");