Compare commits

..

15 Commits

Author SHA1 Message Date
CodeDevMLH
ad2e761bbd Update manifest.json for release v1.6.1.32 [skip ci] 2026-02-14 15:57:28 +00:00
CodeDevMLH
85f90e8fbb Bump version to 1.6.1.32
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 50s
2026-02-14 16:56:39 +01:00
CodeDevMLH
9f5f607168 Refactor video playback handling for active slides and improve mute functionality 2026-02-14 16:56:23 +01:00
CodeDevMLH
108a644983 Update manifest.json for release v1.6.1.31 [skip ci] 2026-02-14 15:41:38 +00:00
CodeDevMLH
ab778f774f Bump version to 1.6.1.31
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 52s
2026-02-14 16:40:48 +01:00
CodeDevMLH
5dcb60487e Implement dynamic mute/unmute functionality based on slideshow state 2026-02-14 16:40:40 +01:00
CodeDevMLH
9a6997f1da Update manifest.json for release v1.6.1.30 [skip ci] 2026-02-14 15:32:46 +00:00
CodeDevMLH
31d315ed8f Bump version to 1.6.1.30
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 54s
2026-02-14 16:31:55 +01:00
CodeDevMLH
2b1301ea0b Refactor video playback management in SlideshowManager for improved performance and auto-unpause functionality 2026-02-14 16:31:38 +01:00
CodeDevMLH
ee8c0b8888 Update manifest.json for release v1.6.1.29 [skip ci] 2026-02-14 15:04:22 +00:00
CodeDevMLH
64ef4915b8 Bump version to 1.6.1.29
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 53s
2026-02-14 16:03:30 +01:00
CodeDevMLH
1f655ed7b6 Enhance SponsorBlock data fetching with caching and improve slide transition logic 2026-02-14 16:03:14 +01:00
CodeDevMLH
0682967591 Update manifest.json for release v1.6.1.28 [skip ci] 2026-02-14 14:38:41 +00:00
CodeDevMLH
7938728f8e Bump version to 1.6.1.28 in project file and manifest
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 53s
2026-02-14 15:37:50 +01:00
CodeDevMLH
a0773c66eb Refactor video playback logic to manage mute state more effectively and improve autoplay handling 2026-02-14 15:37:44 +01:00
3 changed files with 82 additions and 49 deletions

View File

@@ -12,7 +12,7 @@
<!-- <TreatWarningsAsErrors>false</TreatWarningsAsErrors> -->
<Title>Jellyfin Media Bar Enhanced Plugin</Title>
<Authors>CodeDevMLH</Authors>
<Version>1.6.1.26</Version>
<Version>1.6.1.32</Version>
<RepositoryUrl>https://github.com/CodeDevMLH/jellyfin-plugin-media-bar-enhanced</RepositoryUrl>
</PropertyGroup>

View File

@@ -1258,9 +1258,20 @@ const ApiUtils = {
*/
async fetchSponsorBlockData(videoId) {
if (!CONFIG.useSponsorBlock) return { intro: null, outro: null };
// Return cached result if available
if (!this._sponsorBlockCache) this._sponsorBlockCache = {};
if (this._sponsorBlockCache[videoId]) {
return this._sponsorBlockCache[videoId];
}
try {
const response = await fetch(`https://sponsor.ajay.app/api/skipSegments?videoID=${videoId}&categories=["intro","outro"]`);
if (!response.ok) return { intro: null, outro: null };
if (!response.ok) {
const result = { intro: null, outro: null };
this._sponsorBlockCache[videoId] = result;
return result;
}
const segments = await response.json();
let intro = null;
@@ -1274,7 +1285,9 @@ const ApiUtils = {
}
});
return { intro, outro };
const result = { intro, outro };
this._sponsorBlockCache[videoId] = result;
return result;
} catch (error) {
console.warn('Error fetching SponsorBlock data:', error);
return { intro: null, outro: null };
@@ -1758,7 +1771,14 @@ const SlideCreator = {
},
'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')) {
if (CONFIG.waitForTrailerToEnd) {
SlideshowManager.nextSlide();
} else {
event.target.playVideo(); // Loop if trailer is shorter than slide duration
}
}
}
},
'onError': (event) => {
@@ -1787,40 +1807,36 @@ const SlideCreator = {
style: "object-fit: cover; object-position: center center; width: 100%; height: 100%; position: absolute; top: 0; left: 0; pointer-events: none;"
};
if (STATE.slideshow.isMuted) {
videoAttributes.muted = "";
}
videoAttributes.muted = "";
backdrop = SlideUtils.createElement("video", videoAttributes);
if (!STATE.slideshow.isMuted) {
backdrop.volume = 0.4;
}
backdrop.volume = 0.4;
STATE.slideshow.videoPlayers[itemId] = backdrop;
backdrop.addEventListener('play', () => {
// backdrop.addEventListener('play', (event) => {
// const slide = document.querySelector(`.slide[data-item-id="${itemId}"]`);
// if (!slide || !slide.classList.contains('active')) {
// console.log(`Local video ${itemId} started playing but is not active, pausing.`);
// event.target.pause();
// event.target.currentTime = 0;
// return;
// }
backdrop.addEventListener('play', (event) => {
const slide = document.querySelector(`.slide[data-item-id="${itemId}"]`);
if (!slide || !slide.classList.contains('active')) {
console.log(`Local video ${itemId} started playing but slide is not active, pausing.`);
event.target.pause();
event.target.currentTime = 0;
return;
}
if (CONFIG.waitForTrailerToEnd && STATE.slideshow.slideInterval) {
STATE.slideshow.slideInterval.stop();
}
});
backdrop.addEventListener('ended', () => {
SlideshowManager.nextSlide();
const slide = document.querySelector(`.slide[data-item-id="${itemId}"]`);
if (slide && slide.classList.contains('active')) {
SlideshowManager.nextSlide();
}
});
backdrop.addEventListener('error', () => {
if (CONFIG.waitForTrailerToEnd) {
const slide = document.querySelector(`.slide[data-item-id="${itemId}"]`);
if (CONFIG.waitForTrailerToEnd && slide && slide.classList.contains('active')) {
SlideshowManager.nextSlide();
}
});
@@ -2275,36 +2291,41 @@ const SlideshowManager = {
if (previousVisibleSlide) {
previousVisibleSlide.classList.remove("active");
previousVisibleSlide.setAttribute("inert", "");
previousVisibleSlide.setAttribute("tabindex", "-1");
// previousVisibleSlide.setAttribute("inert", "");
// previousVisibleSlide.setAttribute("tabindex", "-1");
}
currentSlide.classList.add("active");
currentSlide.removeAttribute("inert");
currentSlide.setAttribute("tabindex", "0");
// Update Play/Pause Button State if it was paused
if (STATE.slideshow.isPaused) {
STATE.slideshow.isPaused = false;
const pauseButton = document.querySelector('.pause-button');
if (pauseButton) {
pauseButton.innerHTML = '<i class="material-icons">pause</i>';
const pauseLabel = LocalizationUtils.getLocalizedString('ButtonPause', 'Pause');
pauseButton.setAttribute("aria-label", pauseLabel);
pauseButton.setAttribute("title", pauseLabel);
}
}
// // Update Play/Pause Button State if it was paused
// if (STATE.slideshow.isPaused) {
// STATE.slideshow.isPaused = false;
// const pauseButton = document.querySelector('.pause-button');
// if (pauseButton) {
// pauseButton.innerHTML = '<i class="material-icons">pause</i>';
// const pauseLabel = LocalizationUtils.getLocalizedString('ButtonPause', 'Pause');
// pauseButton.setAttribute("aria-label", pauseLabel);
// pauseButton.setAttribute("title", pauseLabel);
// }
// }
// Manage Video Playback: Stop others, Play current
// 1. Pause all other YouTube players
// 1. Stop all other YouTube players and local video elements
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') {
if (!p) return;
// YouTube player
if (typeof p.pauseVideo === 'function') {
p.pauseVideo();
}
// HTML5 <video> element (local trailers)
if (p instanceof HTMLVideoElement) {
p.pause();
p.muted = true;
p.currentTime = 0;
}
}
});
}
@@ -2313,13 +2334,24 @@ const SlideshowManager = {
document.querySelectorAll('video').forEach(video => {
if (!video.closest(`.slide[data-item-id="${currentItemId}"]`)) {
video.pause();
video.muted = true;
}
});
// 3. Play and Reset current video
const videoBackdrop = currentSlide.querySelector('.video-backdrop');
// Auto-unpause when a video slide becomes active
if (videoBackdrop && STATE.slideshow.isPaused) {
STATE.slideshow.isPaused = false;
const pauseButton = document.querySelector('.pause-button');
if (pauseButton) {
pauseButton.innerHTML = '<i class="material-icons">pause</i>';
const pauseLabel = LocalizationUtils.getLocalizedString('ButtonPause', 'Pause');
pauseButton.setAttribute("aria-label", pauseLabel);
pauseButton.setAttribute("title", pauseLabel);
}
}
// Update mute button visibility
const muteButton = document.querySelector('.mute-button');
if (muteButton) {
@@ -2339,8 +2371,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));
}
@@ -2365,6 +2397,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) {

View File

@@ -9,12 +9,12 @@
"imageUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/raw/branch/main/logo.png",
"versions": [
{
"version": "1.6.1.27",
"version": "1.6.1.32",
"changelog": "- fix tv mode issue\n- refactor video playback management",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.6.1.27/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "44b532e881c7ed128d6e76e387f41710",
"timestamp": "2026-02-14T14:22:58Z"
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.6.1.32/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "8d12099d8b1972412b6c300eeddc0c1b",
"timestamp": "2026-02-14T15:57:28Z"
},
{
"version": "1.6.0.2",