Compare commits

...

11 Commits

Author SHA1 Message Date
CodeDevMLH
bf261eba96 Update manifest.json for release v1.6.0.2 [skip ci] 2026-02-10 21:44:36 +00:00
CodeDevMLH
e3116c30cf Bump version to 1.6.0.2
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 50s
2026-02-10 22:43:47 +01:00
CodeDevMLH
bb39c91d32 Enhance custom trailer URL handling to support Jellyfin Item IDs and standard URLs 2026-02-10 22:43:40 +01:00
CodeDevMLH
4e0c74614a Update manifest.json for release v1.6.0.1 [skip ci] 2026-02-10 21:27:25 +00:00
CodeDevMLH
b61bf92437 Bump version to 1.6.0.1 in project files and manifest
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 53s
2026-02-10 22:26:32 +01:00
CodeDevMLH
dfbd6ce964 Enable autoplay for video playback in SlideUtils 2026-02-10 22:26:28 +01:00
CodeDevMLH
f1cbcad177 Update manifest.json for release v1.6.0.0 [skip ci] 2026-02-10 21:18:26 +00:00
CodeDevMLH
feedd5d95f Bump version to 1.6.0.0
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 50s
2026-02-10 22:17:36 +01:00
CodeDevMLH
87d82cca15 Enhance trailer handling: support object format for trailer URLs and add widget referrer for YouTube embeds 2026-02-10 22:17:24 +01:00
CodeDevMLH
a70746e095 Update manifest.json for release v1.5.1.3 [skip ci] 2026-02-10 20:12:59 +00:00
CodeDevMLH
f32283e0bf Bump version to 1.5.1.3 and update changelog for release
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 54s
2026-02-10 21:12:05 +01:00
4 changed files with 73 additions and 22 deletions

View File

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

View File

@@ -164,7 +164,7 @@
.homeSectionsContainer {
position: relative;
margin-top: 65vh;
top: 65vh;
z-index: 6;
}

View File

@@ -742,7 +742,9 @@ const SlideUtils = {
iv_load_policy: 3,
rel: 0,
playsinline: 1,
origin: window.location.origin
origin: window.location.origin,
widget_referrer: window.location.href,
enablejsapi: 1
}
});
});
@@ -1338,7 +1340,7 @@ const ApiUtils = {
/**
* Fetches the first local trailer for an item
* @param {string} itemId - Item ID
* @returns {Promise<string|null>} Stream URL or null
* @returns {Promise<Object|null>} Trailer data object {id, url} or null
*/
async fetchLocalTrailer(itemId) {
try {
@@ -1358,8 +1360,11 @@ const ApiUtils = {
const trailer = trailers[0];
const mediaSourceId = trailer.MediaSources && trailer.MediaSources[0] ? trailer.MediaSources[0].Id : trailer.Id;
// Construct stream URL
return `${STATE.jellyfinData.serverAddress}/Videos/${trailer.Id}/stream.mp4?Static=true&mediaSourceId=${mediaSourceId}&api_key=${STATE.jellyfinData.accessToken}`;
// Return object with ID and URL
return {
id: trailer.Id,
url: `${STATE.jellyfinData.serverAddress}/Videos/${trailer.Id}/stream.mp4?Static=true&mediaSourceId=${mediaSourceId}&api_key=${STATE.jellyfinData.accessToken}`
};
}
return null;
} catch (error) {
@@ -1571,8 +1576,24 @@ const SlideCreator = {
// 1a. Custom URL override
if (STATE.slideshow.customTrailerUrls && STATE.slideshow.customTrailerUrls[itemId]) {
trailerUrl = STATE.slideshow.customTrailerUrls[itemId];
console.log(`Using custom trailer URL for ${itemId}: ${trailerUrl}`);
const customValue = STATE.slideshow.customTrailerUrls[itemId];
// Check if the custom value is a Jellyfin Item ID (GUID)
const guidMatch = customValue.match(/^([0-9a-f]{32})$/i);
if (guidMatch) {
const videoId = guidMatch[1];
console.log(`Using custom local video ID for ${itemId}: ${videoId}`);
trailerUrl = {
id: videoId,
url: `${STATE.jellyfinData.serverAddress}/Videos/${videoId}/stream.mp4?Static=true&api_key=${STATE.jellyfinData.accessToken}`
};
} else {
// Assume it's a standard URL (YouTube, etc.)
trailerUrl = customValue;
console.log(`Using custom trailer URL for ${itemId}: ${trailerUrl}`);
}
}
// 1b. Check Local Trailer if preferred
else if (CONFIG.preferLocalTrailers && item.LocalTrailerCount > 0 && item.localTrailerUrl) {
@@ -1597,12 +1618,17 @@ const SlideCreator = {
let videoId = null;
try {
const urlObj = new URL(trailerUrl);
if (urlObj.hostname.includes('youtube.com') || urlObj.hostname.includes('youtu.be')) {
let urlToCheck = trailerUrl;
if (typeof trailerUrl === 'object' && trailerUrl.url) {
urlToCheck = trailerUrl.url;
}
const urlObjChecked = new URL(urlToCheck);
if (urlObjChecked.hostname.includes('youtube.com') || urlObjChecked.hostname.includes('youtu.be')) {
isYoutube = true;
videoId = urlObj.searchParams.get('v');
if (!videoId && urlObj.hostname.includes('youtu.be')) {
videoId = urlObj.pathname.substring(1);
videoId = urlObjChecked.searchParams.get('v');
if (!videoId && urlObjChecked.hostname.includes('youtu.be')) {
videoId = urlObjChecked.pathname.substring(1);
}
}
} catch (e) {
@@ -1633,7 +1659,9 @@ const SlideCreator = {
rel: 0,
loop: 0,
playsinline: 1,
origin: window.location.origin
origin: window.location.origin,
widget_referrer: window.location.href,
enablejsapi: 1
};
// Determine video quality
@@ -1746,7 +1774,7 @@ const SlideCreator = {
const videoAttributes = {
className: "backdrop video-backdrop",
src: trailerUrl,
src: (typeof trailerUrl === 'object' ? trailerUrl.url : trailerUrl),
autoplay: false,
preload: "auto",
loop: false,
@@ -2037,11 +2065,20 @@ const SlideCreator = {
/**
* Creates a trailer button
* @param {string} url - Trailer URL
* @param {string|Object} trailerInfo - Trailer URL string or object {id, url}
* @returns {HTMLElement} Trailer button element
*/
createTrailerButton(url) {
createTrailerButton(trailerInfo) {
const trailerText = LocalizationUtils.getLocalizedString('Trailer', 'Trailer');
let url = trailerInfo;
let localTrailerId = null;
if (typeof trailerInfo === 'object' && trailerInfo !== null) {
url = trailerInfo.url;
localTrailerId = trailerInfo.id;
}
return SlideUtils.createElement("button", {
className: "detailButton trailer-button",
innerHTML: `<span class="material-icons">movie</span> <span class="trailer-text">${trailerText}</span>`,
@@ -2049,7 +2086,13 @@ const SlideCreator = {
onclick: (e) => {
e.preventDefault();
e.stopPropagation();
SlideUtils.openVideoModal(url);
if (localTrailerId) {
// Play local trailer using native player
ApiUtils.playItem(localTrailerId);
} else {
SlideUtils.openVideoModal(url);
}
},
});
},

View File

@@ -9,12 +9,20 @@
"imageUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/raw/branch/main/logo.png",
"versions": [
{
"version": "1.5.1.2",
"version": "1.6.0.2",
"changelog": "- add local trailer support on trailer button\nfix: iOS/MacOS playback issue?",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.6.0.2/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "335a682c714e3e3178f9444fc36668a0",
"timestamp": "2026-02-10T21:44:35Z"
},
{
"version": "1.5.1.3",
"changelog": "- fix: iOS/MacOS playback issue?",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.5.1.2/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "93fa8dec096d7f032a039d0a8a35241a",
"timestamp": "2026-02-10T17:39:21Z"
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.5.1.3/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "9d9dbed453673d4b78acf2adaaaee126",
"timestamp": "2026-02-10T20:12:59Z"
},
{
"version": "1.5.0.28",