Compare commits

..

43 Commits

Author SHA1 Message Date
CodeDevMLH
05128ebc7e Update manifest.json for release v1.3.0.1 [skip ci] 2026-02-04 01:14:20 +00:00
CodeDevMLH
3bad812e96 Bump version to 1.3.0.1
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 54s
2026-02-04 02:13:29 +01:00
CodeDevMLH
1872a744a7 Update manifest.json for release v1.3.0.0 [skip ci] 2026-02-04 00:07:16 +00:00
CodeDevMLH
83441a3c4f Bump version to 1.3.0.0
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 1m0s
2026-02-04 01:06:22 +01:00
CodeDevMLH
49ad41c3f6 Enhance custom media ID functionality with manual trailer override 2026-02-04 01:06:12 +01:00
CodeDevMLH
984a41b180 Update manifest.json for release v1.2.3.7 [skip ci] 2026-01-28 22:39:54 +00:00
CodeDevMLH
c8421d12b0 Bump version to 1.2.3.7 and update changelog for release
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 57s
2026-01-28 23:39:03 +01:00
CodeDevMLH
b5d38629d2 Update manifest.json for release v1.2.3.6 [skip ci] 2026-01-28 21:31:54 +00:00
CodeDevMLH
8f4adece49 Bump version to 1.2.3.6 and update changelog for release
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 58s
2026-01-28 22:31:01 +01:00
CodeDevMLH
cfebccc289 Update manifest.json for release v1.2.3.5 [skip ci] 2026-01-28 20:21:21 +00:00
CodeDevMLH
2613fd7acf Update version to 1.2.3.5 in project file and manifest.json
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 1m20s
2026-01-28 21:20:06 +01:00
CodeDevMLH
bb10b9c15e Merge branch 'main' of ssh://git.mahom03-spacecloud.de:44322/CodeDevMLH/jellyfin-plugin-media-bar-enhanced 2026-01-28 21:16:52 +01:00
CodeDevMLH
a9ad8d65e4 Merge branch 'main' of ssh://git.mahom03-spacecloud.de:44322/CodeDevMLH/jellyfin-plugin-media-bar-enhanced [skip-ci] 2026-01-28 02:15:28 +01:00
CodeDevMLH
e7232da38b Update manifest.json for release v1.2.3.4 [skip ci] 2026-01-28 01:09:39 +00:00
CodeDevMLH
53bd1d23c7 Update manifest.json for release v1.2.3.4 with changelog and source URL adjustments
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 57s
2026-01-28 02:07:25 +01:00
CodeDevMLH
5643ebfd28 Update manifest.json for release v1.2.3.3 [skip ci] 2026-01-28 01:05:46 +00:00
CodeDevMLH
bed2fbaa76 Bump version to 1.2.3.4 and update release automation to generate commit log
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 58s
2026-01-28 02:04:45 +01:00
CodeDevMLH
05f64bc3d7 Update manifest.json for release v1.2.3.3 [skip ci] 2026-01-28 00:45:20 +00:00
CodeDevMLH
277433581c Bump version to 1.2.3.3 and update manifest with changelog for button positioning adjustments
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 58s
2026-01-28 01:44:23 +01:00
CodeDevMLH
44f0b1cb38 Update manifest.json for release v1.2.3.2 [skip ci] 2026-01-28 00:30:37 +00:00
CodeDevMLH
d31dcbabdc Bump version to 1.2.3.2 and update manifest with changelog for button adjustments on small screens
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 1m1s
2026-01-28 01:29:42 +01:00
CodeDevMLH
4ed6509505 Update manifest.json for release v1.2.3.1 [skip ci] 2026-01-28 00:17:29 +00:00
CodeDevMLH
6427b8422a Bump version to 1.2.3.1 and update manifest with changelog for button layout adjustments on small screens
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 56s
2026-01-28 01:16:38 +01:00
CodeDevMLH
ebfbe1d563 Update manifest.json for release v1.2.3.0 [skip ci] 2026-01-27 23:54:43 +00:00
CodeDevMLH
67e5d8e4d2 Bump version to 1.2.3.0 and update manifest with changelog for button display fixes on small screens
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 56s
2026-01-28 00:53:50 +01:00
CodeDevMLH
d68ba7e846 Update manifest.json for release v1.2.2.0 [skip ci] 2026-01-24 22:53:55 +00:00
CodeDevMLH
0444cf333d Bump version to 1.2.2.0 and update manifest with changelog for visibility fixes
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 1m0s
2026-01-24 23:52:59 +01:00
CodeDevMLH
10279e97d9 Comment out CHANGELOG body in release automation workflow 2026-01-23 01:18:22 +01:00
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
CodeDevMLH
60593dc855 Update manifest.json for release v1.1.1.0 [skip ci] 2026-01-08 14:54:58 +00:00
CodeDevMLH
0edde43720 Update version to 1.1.1.0
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 1m3s
2026-01-08 15:53:56 +01:00
CodeDevMLH
0f6938a91d Add stopAllPlayback method to pause all video playback when navigating away from home screen 2026-01-08 15:52:46 +01:00
9 changed files with 390 additions and 51 deletions

View File

@@ -24,6 +24,8 @@ jobs:
uses: actions/checkout@v6
with:
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0
- name: Setup .NET
uses: actions/setup-dotnet@v5
@@ -94,16 +96,52 @@ jobs:
commit_message: "Update manifest.json for release v${{ env.VERSION }} [skip ci]"
file_pattern: manifest.json
- name: Generate Commit Log
if: success()
shell: bash
run: |
echo "Generating commit log since last tag..."
# Get the previous tag
PREV_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
if [ -z "$PREV_TAG" ]; then
echo "No previous tag found. Getting all commits."
start_range=""
else
echo "Previous tag: $PREV_TAG"
start_range="$PREV_TAG.."
fi
echo "### What's Changed" > commit_log.md
echo "" >> commit_log.md
git log --pretty=format:"- %s (%h) by @%an" $start_range >> commit_log.md
# Combine Changelog from manifest (if exists) and commit log
if [ -n "${{ env.CHANGELOG }}" ]; then
echo "${{ env.CHANGELOG }}" > release_body.txt
echo "" >> release_body.txt
echo "" >> release_body.txt
cat commit_log.md >> release_body.txt
else
cat commit_log.md > release_body.txt
fi
# Debug output
cat release_body.txt
- name: Create Release
uses: softprops/action-gh-release@v2
with:
tag_name: "v${{ env.VERSION }}"
name: "v${{ env.VERSION }}"
body: ${{ env.CHANGELOG }}
# body: ${{ env.CHANGELOG }}
files: ${{ env.ZIP_PATH }}
draft: false
prerelease: false
generate_release_notes: true
generate_release_notes: false
body_path: release_body.txt
# Update Message in Remote Repository
- name: Checkout Central Manifest Repo

View File

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

View File

@@ -16,7 +16,7 @@
<a is="emby-linkbutton" class="raised raised-mini emby-button" style="margin-left: 2em;"
target="_blank" href="https://github.com/CodeDevMLH/jellyfin-plugin-media-bar-enhanced">
<i class="md-icon button-icon button-icon-left secondaryText"></i>
<span>Help</span>
<span>${Help}</span>
</a>
</div>
<hr style="max-width: 800px; margin: 1em 0;">
@@ -109,20 +109,25 @@
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="CustomMediaIds">Media/Collection/Playlist
IDs
(Comma or Newline separated)</label>
(Newline or Comma separated)</label>
<textarea is="emby-textarea" id="CustomMediaIds" name="CustomMediaIds"
style="width: 100%; height: 150px; font-family: monospace;"></textarea>
<div class="fieldDescription" id="customMediaIdsDesc">Enter the IDs of the items you want to
show in the slideshow.
You can separate them by comma or new line.
<div class="fieldDescription" id="customMediaIdsDesc">Enter the IDs of the items you want to show in the slideshow.
You can separate them by new line or comma.
<br>
<b>Manual Trailer Override:</b> You can specify a YouTube URL for an item by adding it in
brackets: <code>ID [https://youtu.be/...]</code>
<br>
You can also add a description after the ID using any separator like space, pipe
(|) or dash (-) (e.g. <code>ID | Description</code>).
Note: The separator MUST NOT be a hex character (0-9, a-f).</div>
<b>Note:</b> If using a <b>Collection Name</b> (instead of an ID) combined with a description, you <b>MUST</b> use
the pipe (|) separator.
<b>Note:</b> The separator MUST NOT be a hex character (0-9, a-f).</div>
<div class="fieldDescription" id="seasonalMediaIdsDesc" style="display: none;">
<b>Seasonal Mode Enabled:</b> Define lines with date ranges (Format: DD.MM-DD.MM |
<i>name</i> | <i>IDs</i>).<br>
Example:<br>
<code>20.10-31.10 | Halloween | ID1, ID2</code><br>
<code>20.10-31.10 | Halloween | ID1, ID2 [https://youtu.be/...]</code><br>
<code>01.12-26.12 | Christmas | ID3, ID4</code><br>
<i>Only lines matching the current date will be used. If no line matches, it will try to
fetch the list.txt or use random items.</i>
@@ -156,6 +161,18 @@
</label>
<div class="fieldDescription">Skip intro/outro segments in YouTube trailers.</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">
<label>
<input is="emby-checkbox" type="checkbox" id="StartMuted" name="StartMuted" />

View File

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

View File

@@ -1,5 +1,5 @@
/*
* Jellyfin Slideshow by M0RPH3US v3.0.6
* Jellyfin Slideshow by M0RPH3US v3.0.9
* Modified by CodeDevMLH v1.1.0.0
*
* New features:
@@ -41,11 +41,11 @@
@keyframes kenBurnsZoomIn {
from {
transform: scale(1);
transform: scale3d(1, 1, 0);
}
to {
transform: scale(1.1);
transform: scale3d(1.1, 1.1, 0.1);
}
}
@@ -128,6 +128,10 @@
transition: width 0.2s ease-in-out;
}
.layout-mobile .splashLogo {
height: 12%;
}
.backdrop.low-quality {
filter: blur(0.5px);
transform: scale(1.01);
@@ -166,6 +170,12 @@
height: 90%;
overflow: hidden;
margin: 0 auto;
pointer-events: auto;
}
#slides-container[style*="display: none"],
#slides-container[style*="visibility: hidden"] {
pointer-events: none !important;
}
.arrow {
@@ -780,6 +790,41 @@
left: 50%;
transform: translate(-50%, -50%);
}
@media (max-width: 400px) {
.button-container {
gap: 10px;
}
.play-button,
.trailer-button {
padding: 8px 14px;
}
.misc-info {
flex-wrap: wrap;
justify-content: center;
gap: 0px 10px;
}
.runTime {
width: 100%;
justify-content: center;
margin-top: 0.5vh;
}
.misc-info .separator-icon:last-of-type {
display: none;
}
.genre {
top: calc(50% + 16vh);
}
.button-container {
top: calc(50% + 27vh);
}
}
}
/*Landscape Mode Phones*/

View File

@@ -1,5 +1,5 @@
/*
* Jellyfin Slideshow by M0RPH3US v3.0.6
* Jellyfin Slideshow by M0RPH3US v3.0.9
* Modified by CodeDevMLH v1.1.0.0
*
* New features:
@@ -42,6 +42,7 @@ const CONFIG = {
fullWidthVideo: true,
enableMobileVideo: false,
showTrailerButton: true,
preferredVideoQuality: "Auto",
enableKeyboardControls: true,
alwaysShowArrows: false,
enableCustomMediaIds: true,
@@ -77,6 +78,7 @@ const STATE = {
videoPlayers: {},
sponsorBlockInterval: null,
isMuted: CONFIG.startMuted,
customTrailerUrls: {},
},
};
@@ -252,31 +254,53 @@ const initLoadingScreen = () => {
const checkInterval = setInterval(() => {
const loginFormLoaded = document.querySelector(".manualLoginForm");
const homePageLoaded =
document.querySelector(".homeSectionsContainer") &&
document.querySelector("#slides-container");
const activeTab = document.querySelector(".pageTabContent.is-active");
if (loginFormLoaded || homePageLoaded) {
clearInterval(progressInterval);
clearInterval(checkInterval);
if (loginFormLoaded) {
finishLoading();
return;
}
progressBar.style.transition = "width 300ms ease-in-out";
progressBar.style.width = "100%";
unfilledBar.style.width = "0%";
if (activeTab) {
const tabIndex = activeTab.getAttribute("data-index");
progressBar.addEventListener('transitionend', () => {
requestAnimationFrame(() => {
const loader = document.querySelector(".bar-loading");
if (loader) {
loader.style.opacity = '0';
setTimeout(() => {
loader.remove();
}, 300);
}
});
})
if (tabIndex === "0") {
const homeSections = document.querySelector(".homeSectionsContainer");
const slidesContainer = document.querySelector("#slides-container");
if (homeSections && slidesContainer) {
finishLoading();
}
} else {
if (
activeTab.children.length > 0 ||
activeTab.innerText.trim().length > 0
) {
finishLoading();
}
}
}
}, 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);
}
});
});
};
};
/**
@@ -321,6 +345,7 @@ const resetSlideshowState = () => {
STATE.slideshow.itemIds = [];
STATE.slideshow.loadedItems = {};
STATE.slideshow.createdSlides = {};
STATE.slideshow.customTrailerUrls = {};
STATE.slideshow.totalItems = 0;
STATE.slideshow.isLoading = false;
};
@@ -820,29 +845,64 @@ const LocalizationUtils = {
throw new Error(`Failed to fetch translations: ${response.statusText}`);
}
/**
* @example
* Standard version
* ```js
* "use strict";
* (self.webpackChunk = self.webpackChunk || []).push([[62634], {
* 30985: function(e) {
* e.exports = JSON.parse('{"Absolute":"..."}')
* }
* }]);
* ```
*
* Minified version
* ```js
* "use strict";(self.webpackChunk=self.webpackChunk||[]).push([[24072],{60715:function(e){e.exports=JSON.parse('{"Absolute":"..."}')}}]);
* ```
*/
const chunkText = await response.text();
const replaceEscaped = (text) =>
text.replace(/\\"/g, '"').replace(/\\n/g, '\n').replace(/\\\\/g, '\\').replace(/\\'/g, "'");
// 1. Try to remove start and end wrappers first
try {
// Matches from start of file to the beginning of JSON.parse('
const START = /^(.*)JSON\.parse\(['"]/gms;
// Matches from the end of the JSON string to the end of the file
const END = /['"]?\)?\s*}?(\r\n|\r|\n)?}?]?\)?;(\r\n|\r|\n)?$/gms;
const jsonString = replaceEscaped(chunkText.replace(START, '').replace(END, ''));
this.translations[locale] = JSON.parse(jsonString);
return;
} catch (e) {
console.error('Failed to parse JSON from standard extraction.');
// Try alternative extraction below
}
// 2. Try to extract only the JSON string directly
let jsonMatch = chunkText.match(/JSON\.parse\(['"](.*?)['"]\)/);
if (jsonMatch) {
let jsonString = jsonMatch[1]
.replace(/\\"/g, '"')
.replace(/\\n/g, '\n')
.replace(/\\\\/g, '\\')
.replace(/\\'/g, "'");
try {
const jsonString = replaceEscaped(jsonMatch[1]);
this.translations[locale] = JSON.parse(jsonString);
return;
} catch (e) {
console.error('Failed to parse JSON from direct extraction.');
// Try direct extraction
}
}
// 3. Fallback: extract everything between the first { and the last }
const jsonStart = chunkText.indexOf('{');
const jsonEnd = chunkText.lastIndexOf('}') + 1;
if (jsonStart !== -1 && jsonEnd > jsonStart) {
const jsonString = chunkText.substring(jsonStart, jsonEnd);
try {
this.translations[locale] = JSON.parse(jsonString);
return;
} catch (e) {
console.error("Failed to parse JSON from chunk:", e);
}
@@ -1252,18 +1312,23 @@ const VisibilityObserver = {
const isVisible =
(window.location.hash === "#/home.html" ||
window.location.hash === "#/home") &&
activeTab &&
activeTab.getAttribute("data-index") === "0";
container.style.display = isVisible ? "block" : "none";
container.style.visibility = isVisible ? "visible" : "hidden";
container.style.pointerEvents = isVisible ? "auto" : "none";
if (isVisible) {
if (STATE.slideshow.slideInterval && !STATE.slideshow.isPaused) {
STATE.slideshow.slideInterval.start();
SlideshowManager.resumeActivePlayback();
}
} else {
if (STATE.slideshow.slideInterval) {
STATE.slideshow.slideInterval.stop();
}
SlideshowManager.stopAllPlayback();
}
},
@@ -1271,11 +1336,11 @@ const VisibilityObserver = {
* Initializes visibility observer
*/
init() {
const observer = new MutationObserver(this.updateVisibility);
const observer = new MutationObserver(() => this.updateVisibility());
observer.observe(document.body, { childList: true, subtree: true });
document.body.addEventListener("click", this.updateVisibility);
window.addEventListener("hashchange", this.updateVisibility);
document.body.addEventListener("click", () => this.updateVisibility());
window.addEventListener("hashchange", () => this.updateVisibility());
this.updateVisibility();
},
@@ -1366,7 +1431,11 @@ const SlideCreator = {
let trailerUrl = null;
// 1. Check for Remote Trailers (YouTube)
if (item.RemoteTrailers && item.RemoteTrailers.length > 0) {
// Priority: Custom Config URL > Metadata RemoteTrailer
if (STATE.slideshow.customTrailerUrls && STATE.slideshow.customTrailerUrls[itemId]) {
trailerUrl = STATE.slideshow.customTrailerUrls[itemId];
console.log(`Using custom trailer URL for ${itemId}: ${trailerUrl}`);
} else if (item.RemoteTrailers && item.RemoteTrailers.length > 0) {
trailerUrl = item.RemoteTrailers[0].Url;
}
@@ -1415,6 +1484,21 @@ const SlideCreator = {
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
if (segments.intro) {
playerVars.start = Math.ceil(segments.intro[1]);
@@ -1444,6 +1528,10 @@ const SlideCreator = {
event.target.setVolume(40);
}
if (typeof event.target.setPlaybackQuality === 'function') {
event.target.setPlaybackQuality(quality);
}
// Only play if this is the active slide
const slide = document.querySelector(`.slide[data-item-id="${itemId}"]`);
if (slide && slide.classList.contains('active')) {
@@ -1492,6 +1580,7 @@ const SlideCreator = {
className: "backdrop video-backdrop",
src: trailerUrl,
autoplay: false,
preload: "auto",
loop: false,
style: "object-fit: cover; width: 100%; height: 100%; pointer-events: none;"
};
@@ -2317,6 +2406,65 @@ const SlideshowManager = {
}
},
/**
* Stops all video playback (YouTube and HTML5)
* Used when navigating away from the home screen
*/
stopAllPlayback() {
// 1. Pause all YouTube players
if (STATE.slideshow.videoPlayers) {
Object.values(STATE.slideshow.videoPlayers).forEach(player => {
try {
if (player && typeof player.pauseVideo === 'function') {
player.pauseVideo();
}
} catch (e) {
console.warn("Error pausing YouTube player:", e);
}
});
}
// 2. Pause all HTML5 videos
const container = document.getElementById("slides-container");
if (container) {
container.querySelectorAll('video').forEach(video => {
try {
video.pause();
} catch (e) {
console.warn("Error pausing HTML5 video:", e);
}
});
}
},
/**
* 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
*/
@@ -2433,10 +2581,25 @@ const SlideshowManager = {
*/
parseCustomIds() {
if (!CONFIG.enableSeasonalContent) {
return CONFIG.customMediaIds
.split(/[\n,]/) // Split by comma or newline
.map((id) => id.trim()) // Remove whitespace
.filter((id) => id); // Remove empty strings
return CONFIG.customMediaIds
.split(/[\n,]/).map((line) => {
const urlMatch = line.match(/\[(.*?)\]/);
let id = line;
if (urlMatch) {
const url = urlMatch[1];
id = line.replace(/\[.*?\]/, '').trim();
const guidMatch = id.match(/([0-9a-f]{32})/i);
if (guidMatch) {
id = guidMatch[1];
} else {
id = id.split('|')[0].trim();
}
STATE.slideshow.customTrailerUrls[id] = url;
}
return id.trim();
})
.map((id) => id.trim())
.filter((id) => id);
} else {
return this.parseSeasonalIds();
}
@@ -2493,7 +2656,22 @@ const SlideshowManager = {
if (isInRange) {
console.log(`Seasonal match found: ${line}`);
const ids = idsPart.split(/[,]/).map(id => id.trim()).filter(id => id);
const ids = idsPart.split(/[,]/).map(line => {
const urlMatch = line.match(/\[(.*?)\]/);
let id = line;
if (urlMatch) {
const url = urlMatch[1];
id = line.replace(/\[.*?\]/, '').trim();
const guidMatch = id.match(/([0-9a-f]{32})/i);
if (guidMatch) {
id = guidMatch[1];
} else {
id = id.split('|')[0].trim();
}
STATE.slideshow.customTrailerUrls[id] = url;
}
return id.trim();
}).filter(id => id);
rawIds.push(...ids);
}
}

View File

@@ -144,6 +144,9 @@ Configure the plugin via **Dashboard** > **Plugins** > **Media Bar Enhanced**.
Define exactly what shows up in your bar.
* **Enable Custom Media IDs**: Restrict the slideshow to a specific list of IDs.
* **Manual Trailer Override**: Add `[YouTube_URL]` after an ID to force a specific trailer.
* Example ID: `a1b2c3d4e5... [https://www.youtube.com/watch?v=VIDEO_ID]`
* Example Collection Name: `Halloween Collection [https://...] | My Description` (Note: Use `|` to separate description from name if using a name instead of an ID)
* **Enable Seasonal Content Mode**: Advanced date-based scheduling.
* Format: `DD.MM-DD.MM | Name | ID1, ID2, ID3`
* Example: `20.10-31.10 | Halloween | <ID_OF_HALLOWEEN_COLLECTION>`

View File

@@ -27,7 +27,8 @@ Setzt deine Commits neu auf die Spitze eines anderen Branches. Die Commit-IDs we
```bash
git checkout dev
git rebase main
git fetch origin
git rebase origin/main
```
| Details | |

View File

@@ -2,12 +2,68 @@
{
"guid": "d7e11d57-819b-4bdd-a88d-53c5f5560225",
"name": "Media Bar Enhanced",
"description": "A jellyfin plugin to display a media bar (featured content) for jellyfin web.",
"overview": "Media Bar for Jellyfin",
"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": "Transforms your Jellyfin home screen with an immersive, fully configurable media slideshow featuring video backdrops.",
"owner": "CodeDevMLH",
"category": "General",
"imageUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/raw/branch/main/logo.png",
"versions": [
{
"version": "1.3.0.1",
"changelog": "- feat: Enhance custom media ID functionality with manual trailer override support",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.3.0.1/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "5a4f555e29c733dabd51169f6ace56eb",
"timestamp": "2026-02-04T01:14:19Z"
},
{
"version": "1.2.3.7",
"changelog": "- Fixes the issue where buttons were cut off on smaller screens such as on S24/S25.\n- Update mediaBarEnhanced.js and mediaBarEnhanced.css with version 3.0.9 from original repo",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.2.3.7/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "fa1bf48cff159cc7dbf0aab48511a37c",
"timestamp": "2026-01-28T22:39:54Z"
},
{
"version": "1.2.2.0",
"changelog": "- Fixes issues with persistent slides-container visibility",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.2.2.0/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "3362f93815845c4e85b66b31bcd0f52c",
"timestamp": "2026-01-24T22:53:55Z"
},
{
"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",
"changelog": "- Add method to pause all video playback when navigating away from home screen",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.1.1.0/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "09da95fc561b11191d23a5cfa30ea731",
"timestamp": "2026-01-08T14:54:57Z"
},
{
"version": "1.1.0.0",
"changelog": "- 'custom media IDs' setting is now enabled by default (no input --> random selection)\n- improve GUID handling in slideshow manager to handle seperator and description",