diff --git a/Jellyfin.Plugin.MediaBarEnhanced/Web/mediaBarEnhanced.js b/Jellyfin.Plugin.MediaBarEnhanced/Web/mediaBarEnhanced.js index 08d3e98..43db69f 100644 --- a/Jellyfin.Plugin.MediaBarEnhanced/Web/mediaBarEnhanced.js +++ b/Jellyfin.Plugin.MediaBarEnhanced/Web/mediaBarEnhanced.js @@ -1723,11 +1723,19 @@ const SlideCreator = { // Create container for YouTube API const videoClass = CONFIG.fullWidthVideo ? "video-backdrop-full" : "video-backdrop-default"; + // Create a wrapper for opacity transition videoBackdrop = SlideUtils.createElement("div", { - className: `backdrop video-backdrop ${videoClass}`, - id: `youtube-player-${itemId}` + className: `backdrop video-backdrop ${videoClass}`, + style: "opacity: 0; transition: opacity 1.2s ease-in-out;" // Start interrupted/transparent }); + const ytPlayerDiv = SlideUtils.createElement("div", { + id: `youtube-player-${itemId}`, + style: "width: 100%; height: 100%;" + }); + + videoBackdrop.appendChild(ytPlayerDiv); + // Initialize YouTube Player SlideUtils.loadYouTubeIframeAPI().then(() => { // Fetch SponsorBlock data @@ -1783,6 +1791,9 @@ const SlideCreator = { event.target._startTime = playerVars.start || 0; event.target._endTime = playerVars.end || undefined; event.target._videoId = videoId; + + // Store reference to wrapper for fading + event.target._wrapperDiv = videoBackdrop; if (STATE.slideshow.isMuted) { event.target.mute(); @@ -1832,6 +1843,13 @@ const SlideCreator = { } }, 'onStateChange': (event) => { + // Fade in when playing + if (event.data === YT.PlayerState.PLAYING) { + if (event.target._wrapperDiv) { + event.target._wrapperDiv.style.opacity = "1"; + } + } + if (event.data === YT.PlayerState.ENDED) { const slide = document.querySelector(`.slide[data-item-id="${itemId}"]`); if (slide && slide.classList.contains('active')) { @@ -1861,7 +1879,7 @@ const SlideCreator = { preload: "none", disablePictureInPicture: true, "data-src": videoSrc, - style: "object-fit: cover; object-position: center center; width: 100%; height: 100%; position: absolute; top: 0; left: 0; pointer-events: none;" + style: "object-fit: cover; object-position: center center; width: 100%; height: 100%; position: absolute; top: 0; left: 0; pointer-events: none; opacity: 0; transition: opacity 1.2s ease-in-out;" }; videoAttributes.muted = ""; @@ -1879,6 +1897,10 @@ const SlideCreator = { event.target.currentTime = 0; return; } + + // Fade in + event.target.style.opacity = "1"; + if (CONFIG.waitForTrailerToEnd && STATE.slideshow.slideInterval) { STATE.slideshow.slideInterval.stop(); }