Compare commits

..

3 Commits

Author SHA1 Message Date
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 54 additions and 24 deletions

View File

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

View File

@@ -1709,13 +1709,6 @@ const SlideCreator = {
event.target._endTime = playerVars.end || undefined; event.target._endTime = playerVars.end || undefined;
event.target._videoId = videoId; 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') { if (typeof event.target.setPlaybackQuality === 'function') {
event.target.setPlaybackQuality(quality); event.target.setPlaybackQuality(quality);
} }
@@ -1725,6 +1718,14 @@ const SlideCreator = {
const isVideoPlayerOpen = document.querySelector('.videoPlayerContainer') || document.querySelector('.youtubePlayerContainer'); const isVideoPlayerOpen = document.querySelector('.videoPlayerContainer') || document.querySelector('.youtubePlayerContainer');
if (slide && slide.classList.contains('active') && !document.hidden && (!isVideoPlayerOpen || isVideoPlayerOpen.classList.contains('hide'))) { 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(); event.target.playVideo();
// Check if it actually started playing after a short delay (handling autoplay blocks) // 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) { if (CONFIG.waitForTrailerToEnd && STATE.slideshow.slideInterval) {
STATE.slideshow.slideInterval.stop(); STATE.slideshow.slideInterval.stop();
} }
} else {
event.target.mute();
} }
}, },
'onStateChange': (event) => { 'onStateChange': (event) => {
if (event.data === YT.PlayerState.ENDED) { 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) => { 'onError': (event) => {
@@ -2297,13 +2303,20 @@ const SlideshowManager = {
// Manage Video Playback: Stop others, Play current // 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) { if (STATE.slideshow.videoPlayers) {
Object.keys(STATE.slideshow.videoPlayers).forEach(id => { Object.keys(STATE.slideshow.videoPlayers).forEach(id => {
if (id !== currentItemId) { if (id !== currentItemId) {
const p = STATE.slideshow.videoPlayers[id]; const p = STATE.slideshow.videoPlayers[id];
if (p && typeof p.pauseVideo === 'function') { if (p) {
p.pauseVideo(); 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 => { videoBackdrop.play().catch(e => {
// Check if it actually started playing after a short delay (handling autoplay blocks) // Check if it actually started playing after a short delay (handling autoplay blocks)
setTimeout(() => { setTimeout(() => {
if (videoBackdrop.paused) { if (videoBackdrop.paused && currentSlide.classList.contains('active')) {
console.warn(`Autoplay blocked for ${itemId}, attempting muted fallback`); console.warn(`Autoplay blocked for ${currentItemId}, attempting muted fallback`);
videoBackdrop.muted = true; videoBackdrop.muted = true;
videoBackdrop.play().catch(err => console.error("Muted fallback failed", err)); 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]) { } else if (STATE.slideshow.videoPlayers && STATE.slideshow.videoPlayers[currentItemId]) {
const player = STATE.slideshow.videoPlayers[currentItemId]; const player = STATE.slideshow.videoPlayers[currentItemId];
if (player && typeof player.loadVideoById === 'function' && player._videoId) { if (player && typeof player.loadVideoById === 'function' && player._videoId) {
// Use loadVideoById to enforce start and end times // If same video is already loaded, just seek and play (much faster)
player.loadVideoById({ let isAlreadyLoaded = false;
videoId: player._videoId, if (typeof player.getVideoData === 'function') {
startSeconds: player._startTime || 0, try {
endSeconds: player._endTime 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) { if (STATE.slideshow.isMuted) {
player.mute(); player.mute();
@@ -2365,6 +2394,7 @@ const SlideshowManager = {
// Check if playback successfully started, otherwise fallback to muted // Check if playback successfully started, otherwise fallback to muted
setTimeout(() => { setTimeout(() => {
if (!currentSlide.classList.contains('active')) return;
if (player.getPlayerState && if (player.getPlayerState &&
player.getPlayerState() !== YT.PlayerState.PLAYING && player.getPlayerState() !== YT.PlayerState.PLAYING &&
player.getPlayerState() !== YT.PlayerState.BUFFERING) { 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", "imageUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/raw/branch/main/logo.png",
"versions": [ "versions": [
{ {
"version": "1.6.1.27", "version": "1.6.1.28",
"changelog": "- fix tv mode issue\n- refactor video playback management", "changelog": "- fix tv mode issue\n- refactor video playback management",
"targetAbi": "10.11.0.0", "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", "sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.6.1.28/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "44b532e881c7ed128d6e76e387f41710", "checksum": "2b44f2ee7399b70c4bfdaae33ff80437",
"timestamp": "2026-02-14T14:22:58Z" "timestamp": "2026-02-14T14:38:40Z"
}, },
{ {
"version": "1.6.0.2", "version": "1.6.0.2",