Compare commits

...

12 Commits

Author SHA1 Message Date
CodeDevMLH
f6ccd0ea5f Update manifest.json for release v1.2.1.0 [skip ci] 2026-01-22 23:50:56 +00:00
CodeDevMLH
47827df047 Update mediaBarEnhanced.js and mediaBarEnhanced.css with version 3.0.8 from original repo
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 1m0s
2026-01-23 00:50:01 +01:00
CodeDevMLH
7fd781c9d0 Update manifest.json for release v1.2.0.0 [skip ci] 2026-01-08 23:30:58 +00:00
CodeDevMLH
6faa8f1a4c Update plugin description in manifest.json for clarity and completeness
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 1m4s
2026-01-09 00:30:00 +01:00
CodeDevMLH
3e05ff1dc9 Update manifest.json for release v1.2.0.0 [skip ci] 2026-01-08 23:15:07 +00:00
CodeDevMLH
fa06179cd3 Update manifest.json to enhance plugin description and overview
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 55s
2026-01-09 00:14:16 +01:00
CodeDevMLH
d8327fc5c9 Update manifest.json for release v1.2.0.0 [skip ci] 2026-01-08 22:16:05 +00:00
CodeDevMLH
9ffe03f0df Update version to 1.2.0.0
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 57s
2026-01-08 23:15:13 +01:00
CodeDevMLH
37e99d7fed Add Preferred Video Quality setting and update playback quality logic 2026-01-08 23:14:59 +01:00
CodeDevMLH
9b0e3762ac Update manifest.json for release v1.1.2.0 [skip ci] 2026-01-08 15:26:55 +00:00
CodeDevMLH
48f93e3480 Update version to 1.1.2.0
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 53s
2026-01-08 16:26:04 +01:00
CodeDevMLH
2e9c093cdc Add resumeActivePlayback method to resume video playback when slideshow is active 2026-01-08 16:25:04 +01:00
6 changed files with 140 additions and 27 deletions

View File

@@ -31,6 +31,7 @@ namespace Jellyfin.Plugin.MediaBarEnhanced.Configuration
public bool AlwaysShowArrows { get; set; } = false; public bool AlwaysShowArrows { get; set; } = false;
public string CustomMediaIds { get; set; } = ""; public string CustomMediaIds { get; set; } = "";
public bool EnableCustomMediaIds { get; set; } = true; public bool EnableCustomMediaIds { get; set; } = true;
public string PreferredVideoQuality { get; set; } = "Auto";
public bool EnableSeasonalContent { get; set; } = false; public bool EnableSeasonalContent { get; set; } = false;
public bool IsEnabled { get; set; } = true; public bool IsEnabled { get; set; } = true;
} }

View File

@@ -156,6 +156,18 @@
</label> </label>
<div class="fieldDescription">Skip intro/outro segments in YouTube trailers.</div> <div class="fieldDescription">Skip intro/outro segments in YouTube trailers.</div>
</div> </div>
<div class="selectContainer">
<label class="selectLabel" for="PreferredVideoQuality">Preferred YouTube Quality</label>
<select is="emby-select" id="PreferredVideoQuality" name="PreferredVideoQuality"
class="emby-select-withcolor emby-select">
<option value="Auto">Auto (Smart)</option>
<option value="Maximum">Maximum (4K+)</option>
<option value="1080p">1080p</option>
<option value="720p">720p</option>
</select>
<div class="fieldDescription">"Auto" selects Maximum if screen width > 1920px, otherwise
1080p.</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription"> <div class="checkboxContainer checkboxContainer-withDescription">
<label> <label>
<input is="emby-checkbox" type="checkbox" id="StartMuted" name="StartMuted" /> <input is="emby-checkbox" type="checkbox" id="StartMuted" name="StartMuted" />

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.1.1.0</Version> <Version>1.2.1.0</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

@@ -1,5 +1,5 @@
/* /*
* Jellyfin Slideshow by M0RPH3US v3.0.6 * Jellyfin Slideshow by M0RPH3US v3.0.8
* Modified by CodeDevMLH v1.1.0.0 * Modified by CodeDevMLH v1.1.0.0
* *
* New features: * New features:
@@ -41,11 +41,11 @@
@keyframes kenBurnsZoomIn { @keyframes kenBurnsZoomIn {
from { from {
transform: scale(1); transform: scale3d(1, 1, 0);
} }
to { to {
transform: scale(1.1); transform: scale3d(1.1, 1.1, 0.1);
} }
} }
@@ -128,6 +128,10 @@
transition: width 0.2s ease-in-out; transition: width 0.2s ease-in-out;
} }
.layout-mobile .splashLogo {
height: 12%;
}
.backdrop.low-quality { .backdrop.low-quality {
filter: blur(0.5px); filter: blur(0.5px);
transform: scale(1.01); transform: scale(1.01);

View File

@@ -1,5 +1,5 @@
/* /*
* Jellyfin Slideshow by M0RPH3US v3.0.6 * Jellyfin Slideshow by M0RPH3US v3.0.8
* Modified by CodeDevMLH v1.1.0.0 * Modified by CodeDevMLH v1.1.0.0
* *
* New features: * New features:
@@ -42,6 +42,7 @@ const CONFIG = {
fullWidthVideo: true, fullWidthVideo: true,
enableMobileVideo: false, enableMobileVideo: false,
showTrailerButton: true, showTrailerButton: true,
preferredVideoQuality: "Auto",
enableKeyboardControls: true, enableKeyboardControls: true,
alwaysShowArrows: false, alwaysShowArrows: false,
enableCustomMediaIds: true, enableCustomMediaIds: true,
@@ -252,31 +253,53 @@ const initLoadingScreen = () => {
const checkInterval = setInterval(() => { const checkInterval = setInterval(() => {
const loginFormLoaded = document.querySelector(".manualLoginForm"); const loginFormLoaded = document.querySelector(".manualLoginForm");
const homePageLoaded = const activeTab = document.querySelector(".pageTabContent.is-active");
document.querySelector(".homeSectionsContainer") &&
document.querySelector("#slides-container");
if (loginFormLoaded || homePageLoaded) { if (loginFormLoaded) {
clearInterval(progressInterval); finishLoading();
clearInterval(checkInterval); return;
}
progressBar.style.transition = "width 300ms ease-in-out"; if (activeTab) {
progressBar.style.width = "100%"; const tabIndex = activeTab.getAttribute("data-index");
unfilledBar.style.width = "0%";
progressBar.addEventListener('transitionend', () => { if (tabIndex === "0") {
requestAnimationFrame(() => { const homeSections = document.querySelector(".homeSectionsContainer");
const loader = document.querySelector(".bar-loading"); const slidesContainer = document.querySelector("#slides-container");
if (loader) {
loader.style.opacity = '0'; if (homeSections && slidesContainer) {
setTimeout(() => { finishLoading();
loader.remove(); }
}, 300); } else {
} if (
}); activeTab.children.length > 0 ||
}) activeTab.innerText.trim().length > 0
) {
finishLoading();
}
}
} }
}, CONFIG.loadingCheckInterval); }, CONFIG.loadingCheckInterval);
const finishLoading = () => {
clearInterval(progressInterval);
clearInterval(checkInterval);
progressBar.style.transition = "width 300ms ease-in-out";
progressBar.style.width = "100%";
unfilledBar.style.width = "0%";
progressBar.addEventListener("transitionend", () => {
requestAnimationFrame(() => {
const loader = document.querySelector(".bar-loading");
if (loader) {
loader.style.opacity = "0";
setTimeout(() => {
loader.remove();
}, 300);
}
});
});
};
}; };
/** /**
@@ -1259,6 +1282,7 @@ const VisibilityObserver = {
if (isVisible) { if (isVisible) {
if (STATE.slideshow.slideInterval && !STATE.slideshow.isPaused) { if (STATE.slideshow.slideInterval && !STATE.slideshow.isPaused) {
STATE.slideshow.slideInterval.start(); STATE.slideshow.slideInterval.start();
SlideshowManager.resumeActivePlayback();
} }
} else { } else {
if (STATE.slideshow.slideInterval) { if (STATE.slideshow.slideInterval) {
@@ -1416,6 +1440,21 @@ const SlideCreator = {
loop: 0 loop: 0
}; };
// Determine video quality
let quality = 'hd1080';
if (CONFIG.preferredVideoQuality === 'Maximum') {
quality = 'highres';
} else if (CONFIG.preferredVideoQuality === '720p') {
quality = 'hd720';
} else if (CONFIG.preferredVideoQuality === '1080p') {
quality = 'hd1080';
} else { // Auto or fallback
// If screen is wider than 1920, prefer highres, otherwise 1080p
quality = window.screen.width > 1920 ? 'highres' : 'hd1080';
}
playerVars.suggestedQuality = quality;
// Apply SponsorBlock start/end times // Apply SponsorBlock start/end times
if (segments.intro) { if (segments.intro) {
playerVars.start = Math.ceil(segments.intro[1]); playerVars.start = Math.ceil(segments.intro[1]);
@@ -1445,6 +1484,10 @@ const SlideCreator = {
event.target.setVolume(40); event.target.setVolume(40);
} }
if (typeof event.target.setPlaybackQuality === 'function') {
event.target.setPlaybackQuality(quality);
}
// Only play if this is the active slide // Only play if this is the active slide
const slide = document.querySelector(`.slide[data-item-id="${itemId}"]`); const slide = document.querySelector(`.slide[data-item-id="${itemId}"]`);
if (slide && slide.classList.contains('active')) { if (slide && slide.classList.contains('active')) {
@@ -1493,6 +1536,7 @@ const SlideCreator = {
className: "backdrop video-backdrop", className: "backdrop video-backdrop",
src: trailerUrl, src: trailerUrl,
autoplay: false, autoplay: false,
preload: "auto",
loop: false, loop: false,
style: "object-fit: cover; width: 100%; height: 100%; pointer-events: none;" style: "object-fit: cover; width: 100%; height: 100%; pointer-events: none;"
}; };
@@ -2349,6 +2393,34 @@ const SlideshowManager = {
} }
}, },
/**
* Resumes playback for the active slide if not globally paused
*/
resumeActivePlayback() {
if (STATE.slideshow.isPaused) return;
const currentItemId = STATE.slideshow.itemIds[STATE.slideshow.currentSlideIndex];
if (!currentItemId) return;
const currentSlide = document.querySelector(`.slide[data-item-id="${currentItemId}"]`);
if (!currentSlide) return;
// 1. Try YouTube Player
const ytPlayer = STATE.slideshow.videoPlayers[currentItemId];
if (ytPlayer && typeof ytPlayer.playVideo === 'function') {
ytPlayer.playVideo();
}
// 2. Try HTML5 Video
const html5Video = currentSlide.querySelector('video');
if (html5Video) {
if (STATE.slideshow.isMuted) {
html5Video.muted = true;
}
html5Video.play().catch(e => console.warn("Error resuming HTML5 video:", e));
}
},
/** /**
* Initializes touch events for swiping * Initializes touch events for swiping
*/ */

View File

@@ -2,12 +2,36 @@
{ {
"guid": "d7e11d57-819b-4bdd-a88d-53c5f5560225", "guid": "d7e11d57-819b-4bdd-a88d-53c5f5560225",
"name": "Media Bar Enhanced", "name": "Media Bar Enhanced",
"description": "A jellyfin plugin to display a media bar (featured content) for jellyfin web.", "description": "A feature-rich fork of the original Media Bar script by MakD that brings your home screen to life.\n\n-> 100% Configurable via Web UI: Manage all features, lists, and settings effortlessly through the plugin configuration page.\n\nKey Highlights:\n- Cinematic Video Backdrops: Supports local & YouTube trailers (incl. SponsorBlock)\n- Custom Content: Curate your slideshow with specific Collections, Playlists, or seasonal events\n\nAdditional Features:\n- Full-width immersive mode\n- Smart resolution handling (up to 4K)\n- Full keyboard navigation & playback control\n- Wait-for-trailer options\n- Customizable pagination & animations\n\nIf you do not have write permissions to the web folder, please also install the file-transformation plugin.",
"overview": "Media Bar for Jellyfin", "overview": "Transforms your Jellyfin home screen with an immersive, fully configurable media slideshow featuring video backdrops.",
"owner": "CodeDevMLH", "owner": "CodeDevMLH",
"category": "General", "category": "General",
"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.2.1.0",
"changelog": "- Update mediaBarEnhanced.js and mediaBarEnhanced.css with version 3.0.8 from original repo",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.2.1.0/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "70defc1fb29a17ff4c9362bf7bdc53b5",
"timestamp": "2026-01-22T23:50:56Z"
},
{
"version": "1.2.0.0",
"changelog": "- Add video quality preference setting (Auto / 1080p / Highres)\n- Set preferred video quality on YouTube player based on setting",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.2.0.0/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "0b6379f68990026240d97fe8f77fbef1",
"timestamp": "2026-01-08T23:30:58Z"
},
{
"version": "1.1.2.0",
"changelog": "- Add method to resume video playback when slideshow is active",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.1.2.0/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "a0e8ff5e59b22a1bdedc916cd5e1c16a",
"timestamp": "2026-01-08T15:26:55Z"
},
{ {
"version": "1.1.1.0", "version": "1.1.1.0",
"changelog": "- Add method to pause all video playback when navigating away from home screen", "changelog": "- Add method to pause all video playback when navigating away from home screen",