diff --git a/Jellyfin.Plugin.MediaBarEnhanced/Web/mediaBarEnhanced.js b/Jellyfin.Plugin.MediaBarEnhanced/Web/mediaBarEnhanced.js index cabce35..9d99188 100644 --- a/Jellyfin.Plugin.MediaBarEnhanced/Web/mediaBarEnhanced.js +++ b/Jellyfin.Plugin.MediaBarEnhanced/Web/mediaBarEnhanced.js @@ -1709,13 +1709,6 @@ const SlideCreator = { event.target._endTime = playerVars.end || undefined; event.target._videoId = videoId; - if (STATE.slideshow.isMuted) { - event.target.mute(); - } else { - event.target.unMute(); - event.target.setVolume(40); - } - if (typeof event.target.setPlaybackQuality === 'function') { event.target.setPlaybackQuality(quality); } @@ -1725,6 +1718,14 @@ const SlideCreator = { const isVideoPlayerOpen = document.querySelector('.videoPlayerContainer') || document.querySelector('.youtubePlayerContainer'); if (slide && slide.classList.contains('active') && !document.hidden && (!isVideoPlayerOpen || isVideoPlayerOpen.classList.contains('hide'))) { + // Set mute state only for active slide + if (STATE.slideshow.isMuted) { + event.target.mute(); + } else { + event.target.unMute(); + event.target.setVolume(40); + } + event.target.playVideo(); // Check if it actually started playing after a short delay (handling autoplay blocks) @@ -1754,11 +1755,16 @@ const SlideCreator = { if (CONFIG.waitForTrailerToEnd && STATE.slideshow.slideInterval) { STATE.slideshow.slideInterval.stop(); } + } else { + event.target.mute(); } }, 'onStateChange': (event) => { if (event.data === YT.PlayerState.ENDED) { - SlideshowManager.nextSlide(); + const slide = document.querySelector(`.slide[data-item-id="${itemId}"]`); + if (slide && slide.classList.contains('active')) { + SlideshowManager.nextSlide(); + } } }, 'onError': (event) => { @@ -2297,13 +2303,20 @@ const SlideshowManager = { // Manage Video Playback: Stop others, Play current - // 1. Pause all other YouTube players + // 1. Pause and mute all other YouTube players if (STATE.slideshow.videoPlayers) { Object.keys(STATE.slideshow.videoPlayers).forEach(id => { if (id !== currentItemId) { const p = STATE.slideshow.videoPlayers[id]; - if (p && typeof p.pauseVideo === 'function') { - p.pauseVideo(); + if (p) { + try { + if (typeof p.pauseVideo === 'function') { + p.pauseVideo(); + if (typeof p.mute === 'function') { + p.mute(); + } + } + } catch (e) { console.warn("Error pausing player", id, e); } } } }); @@ -2339,8 +2352,8 @@ const SlideshowManager = { videoBackdrop.play().catch(e => { // Check if it actually started playing after a short delay (handling autoplay blocks) setTimeout(() => { - if (videoBackdrop.paused) { - console.warn(`Autoplay blocked for ${itemId}, attempting muted fallback`); + if (videoBackdrop.paused && currentSlide.classList.contains('active')) { + console.warn(`Autoplay blocked for ${currentItemId}, attempting muted fallback`); videoBackdrop.muted = true; videoBackdrop.play().catch(err => console.error("Muted fallback failed", err)); } @@ -2349,12 +2362,28 @@ const SlideshowManager = { } else if (STATE.slideshow.videoPlayers && STATE.slideshow.videoPlayers[currentItemId]) { const player = STATE.slideshow.videoPlayers[currentItemId]; if (player && typeof player.loadVideoById === 'function' && player._videoId) { - // Use loadVideoById to enforce start and end times - player.loadVideoById({ - videoId: player._videoId, - startSeconds: player._startTime || 0, - endSeconds: player._endTime - }); + // If same video is already loaded, just seek and play (much faster) + let isAlreadyLoaded = false; + if (typeof player.getVideoData === 'function') { + try { + const data = player.getVideoData(); + if (data && data.video_id === player._videoId) { + isAlreadyLoaded = true; + } + } catch (e) { /* player not fully ready */ } + } + + if (isAlreadyLoaded) { + player.seekTo(player._startTime || 0); + player.playVideo(); + } else { + // Full load needed (first time or different video) + player.loadVideoById({ + videoId: player._videoId, + startSeconds: player._startTime || 0, + endSeconds: player._endTime + }); + } if (STATE.slideshow.isMuted) { player.mute(); @@ -2365,6 +2394,7 @@ const SlideshowManager = { // Check if playback successfully started, otherwise fallback to muted setTimeout(() => { + if (!currentSlide.classList.contains('active')) return; if (player.getPlayerState && player.getPlayerState() !== YT.PlayerState.PLAYING && player.getPlayerState() !== YT.PlayerState.BUFFERING) {