..
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
let title = 'Spotlight'; // Title of the slideshow
|
let title = 'Spotlight'; // Title of the slideshow TBD
|
||||||
let listFileName = 'list.txt'; // Name of the file containing the list of movie IDs
|
let listFileName = 'list.txt'; // Name of the file containing the list of movie IDs
|
||||||
let token = 'YOURAPIKEYHERE'; // Your Jellyfin API key
|
let token = 'YOURAPIKEYHERE'; // Your Jellyfin API key
|
||||||
let moviesSeriesBoth = 3; // 1 for movies, 2 for series, 3 for both
|
let moviesSeriesBoth = 3; // 1 for movies, 2 for series, 3 for both
|
||||||
@@ -6,43 +6,88 @@ let shuffleInterval = 15000; // Time in milliseconds before the next slide is sh
|
|||||||
let useTrailers = true; // Set to false to disable trailers
|
let useTrailers = true; // Set to false to disable trailers
|
||||||
let setRandomMovie = true; // Set to false to disable random movie selection from the list
|
let setRandomMovie = true; // Set to false to disable random movie selection from the list
|
||||||
let showOnOtherPages = false; // Set to true to show the slideshow on all pages eg. favorites tab, requests tab, etc.
|
let showOnOtherPages = false; // Set to true to show the slideshow on all pages eg. favorites tab, requests tab, etc.
|
||||||
//let showTitle = false; // Set to false to hide the title
|
//let showTitle = false; // Set to false to hide the title TBD
|
||||||
|
let disableTrailerControls = true; // Set to false to enable trailer controls
|
||||||
|
let setMuted = true; // Set to false to disable unmuting the video on hover
|
||||||
let umuteOnHover = true; // Set to false to disable unmuting the video on hover
|
let umuteOnHover = true; // Set to false to disable unmuting the video on hover
|
||||||
let isMuted = true; // Set to false to start with sound
|
let unmutedVolume = 20; // Set the volume level when the video is unmuted
|
||||||
let useSponsorBlock = true; // Set to true to use SponsorBlock data to skip intro/outro segments of trailers
|
let useSponsorBlock = true; // Set to true to use SponsorBlock data to skip intro/outro segments of trailers
|
||||||
let plotMaxLength = 550; // Maximum number of characters in the plot
|
let plotMaxLength = 550; // Maximum number of characters in the plot
|
||||||
let trailerMaxLength = 0; // Default value 0; length measured in ms
|
let trailerMaxLength = 0; // Default value 0; length measured in ms, set to 0 to disable, could be used instead of SponsorBlock
|
||||||
|
let isMuted = true; // Default value true; set to false to start the video unmuted
|
||||||
|
|
||||||
|
|
||||||
|
// variables
|
||||||
let isChangingSlide = false, player = null, slideChangeTimeout = null, isHomePageActive = false;
|
let isChangingSlide = false, player = null, slideChangeTimeout = null, isHomePageActive = false;
|
||||||
let currentLocation = window.top.location.href;
|
let currentLocation = window.top.location.href;
|
||||||
let movieList = [], currentMovieIndex = 0;
|
let movieList = [], currentMovieIndex = 0;
|
||||||
let previousMovies = [];
|
let previousMovies = [];
|
||||||
let forwardMovies = [];
|
let forwardMovies = [];
|
||||||
|
|
||||||
|
if (setMuted) {
|
||||||
|
const slidesContainer = document.getElementById('slides-container');
|
||||||
|
slidesContainer.addEventListener('mouseenter', () => {
|
||||||
|
if (player) {
|
||||||
|
player.unMute();
|
||||||
|
isMuted = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
slidesContainer.addEventListener('mouseleave', () => {
|
||||||
|
if (player) {
|
||||||
|
player.mute();
|
||||||
|
isMuted = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Get SponsorBlock-Data for the outro segment of the trailer
|
// Get SponsorBlock-Data for the outro segment of the trailer
|
||||||
//function fetchSponsorBlockOutro(videoId) {
|
//function fetchSponsorBlockOutro(videoId) {
|
||||||
const fetchSponsorBlockOutro = (videoId) => {
|
// @deprecated
|
||||||
|
const fetchSponsorBlockOutroOLD = (videoId) => {
|
||||||
return fetch(`https://sponsor.ajay.app/api/skipSegments?videoID=${videoId}&category=outro`)
|
return fetch(`https://sponsor.ajay.app/api/skipSegments?videoID=${videoId}&category=outro`)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(segments => { segments.length > 0 ? segments[0].segment : null; })
|
.then(segments => {
|
||||||
|
return segments.length > 0 ? segments[0].segment : null;
|
||||||
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.error('Error fetching SponsorBlock data:', error);
|
console.error('Error fetching SponsorBlock data:', error);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fetchSponsorBlockOutro = async (videoId) => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`https://sponsor.ajay.app/api/skipSegments?videoID=${videoId}&category=outro`);
|
||||||
|
const segments = await response.json();
|
||||||
|
if (segments.length > 0 && Array.isArray(segments[0].segment)) {
|
||||||
|
return segments[0].segment; // returns array: [start, end]
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching SponsorBlock data:', error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// Monitor the video player for the outro segment
|
// Monitor the video player for the outro segment
|
||||||
|
let monitorOutroInterval = null; // Global interval variable
|
||||||
function monitorOutro(player, outroSegment) {
|
function monitorOutro(player, outroSegment) {
|
||||||
const interval = setInterval(() => {
|
if (monitorOutroInterval) { // Clear the interval if it's already running
|
||||||
|
clearInterval(monitorOutroInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
monitorOutroInterval = setInterval(() => {
|
||||||
if (!outroSegment || !player) {
|
if (!outroSegment || !player) {
|
||||||
clearInterval(interval);
|
console.log('Invalid outro segment or player not initialized');
|
||||||
|
clearInterval(monitorOutroInterval);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentTime = player.getCurrentTime();
|
const currentTime = player.getCurrentTime();
|
||||||
if (currentTime >= outroSegment[0] && currentTime < outroSegment[1]) {
|
if (currentTime >= outroSegment[0] && currentTime < outroSegment[1]) {
|
||||||
clearInterval(interval);
|
clearInterval(monitorOutroInterval);
|
||||||
player.stopVideo(); // stop video
|
player.stopVideo(); // stop video
|
||||||
setTimeout(fetchRandomMovie, 100); // fetch next movie
|
setTimeout(fetchRandomMovie, 100); // fetch next movie
|
||||||
}
|
}
|
||||||
@@ -247,13 +292,11 @@ const createSlideElement = (movie, hasVideo = false) => {
|
|||||||
width: '100%',
|
width: '100%',
|
||||||
videoId,
|
videoId,
|
||||||
playerVars: {
|
playerVars: {
|
||||||
mute: 0, // Change to start the video muted MARK: set muted, not officaly refreneced by youtube API, but working...
|
mute: isMuted ? 1 : 0, // CHeck if the video should start muted
|
||||||
controls: 0, // Hide the controls
|
controls: disableTrailerControls ? 0 : 1, // Hide the controls
|
||||||
disablekb: 1, // Disable keyboard controls
|
disablekb: 1, // Disable keyboard controls
|
||||||
fs: 1, // Enavle fullscreen
|
fs: 1, // Enavle fullscreen
|
||||||
rel: 0, // Disable related videos
|
iv_load_policy: 3, // Disable annotations
|
||||||
modestbranding: 1, // Hide the YouTube logo
|
|
||||||
showinfo: 0, // Hide the video title
|
|
||||||
},
|
},
|
||||||
events: {
|
events: {
|
||||||
'onReady': event => {
|
'onReady': event => {
|
||||||
@@ -266,7 +309,7 @@ const createSlideElement = (movie, hasVideo = false) => {
|
|||||||
console.log('No outro segment found/provided');
|
console.log('No outro segment found/provided');
|
||||||
}
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
console.error('Error fetching SponsorBlock outro segment:', error);
|
console.error('Error reading SponsorBlock outro segment:', error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (trailerMaxLength > 0) {
|
if (trailerMaxLength > 0) {
|
||||||
@@ -283,7 +326,7 @@ const createSlideElement = (movie, hasVideo = false) => {
|
|||||||
if (isMuted) {
|
if (isMuted) {
|
||||||
event.target.setVolume(0); // Mute the video if the setting is MuteOn
|
event.target.setVolume(0); // Mute the video if the setting is MuteOn
|
||||||
} else {
|
} else {
|
||||||
event.target.setVolume(4);
|
event.target.setVolume(unmutedVolume); // Set the volume, value between 0 and 100
|
||||||
}
|
}
|
||||||
event.target.playVideo();
|
event.target.playVideo();
|
||||||
},
|
},
|
||||||
@@ -320,6 +363,7 @@ const createSlideElement = (movie, hasVideo = false) => {
|
|||||||
'onError': () => {
|
'onError': () => {
|
||||||
console.error(`YouTube prevented playback of '${movie.Name}'`);
|
console.error(`YouTube prevented playback of '${movie.Name}'`);
|
||||||
if (player) {
|
if (player) {
|
||||||
|
clearInterval(monitorOutroInterval);
|
||||||
player.destroy();
|
player.destroy();
|
||||||
player = null;
|
player = null;
|
||||||
}
|
}
|
||||||
@@ -344,21 +388,7 @@ const createSlideElement = (movie, hasVideo = false) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
videoContainer.addEventListener('mouseenter', () => {
|
|
||||||
if (player && umuteOnHover) {
|
|
||||||
player.unMute();
|
|
||||||
isMuted = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
videoContainer.addEventListener('mouseleave', () => {
|
|
||||||
if (player && umuteOnHover) {
|
|
||||||
player.mute();
|
|
||||||
isMuted = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
console.log(`Trailer disabled for '${movie.Name}'`);
|
|
||||||
startSlideChangeTimer();
|
startSlideChangeTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,12 +1,15 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.1/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.1/css/all.min.css">
|
||||||
<title>Jellyfin Spotlight v2.5.0 Fork v1.2</title>
|
<title>Jellyfin Spotlight v2.5.0 Fork v1.2</title>
|
||||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
<link rel="stylesheet"
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
||||||
<link rel="stylesheet" href="styles.css">
|
<link rel="stylesheet" href="styles.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="slides-container"></div>
|
<div id="slides-container"></div>
|
||||||
<div id="video-overlay" style="display: none;">
|
<div id="video-overlay" style="display: none;">
|
||||||
@@ -18,4 +21,5 @@
|
|||||||
<script src="script.js"></script>
|
<script src="script.js"></script>
|
||||||
<script src="https://www.youtube.com/iframe_api"></script>
|
<script src="https://www.youtube.com/iframe_api"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
@@ -208,6 +208,7 @@ body {
|
|||||||
max-width: 96vw;
|
max-width: 96vw;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
-webkit-line-clamp: 2;
|
-webkit-line-clamp: 2;
|
||||||
|
line-clamp: 2;
|
||||||
max-height: 7.8em;
|
max-height: 7.8em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
@@ -307,17 +308,17 @@ body {
|
|||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.slide:hover .clickable-overlay {}
|
/*.slide:hover .clickable-overlay {}*/
|
||||||
|
|
||||||
.slide:hover .clickable-overlay::before {
|
.slide:hover .clickable-overlay::before {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
backdrop-filter: blur(0px);
|
backdrop-filter: blur(0px);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
.slide:hover .logo {}
|
.slide:hover .logo {}
|
||||||
|
|
||||||
.slide:hover .plot {}
|
.slide:hover .plot {}
|
||||||
|
*/
|
||||||
.slide:hover .lorem-ipsum::before {
|
.slide:hover .lorem-ipsum::before {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
backdrop-filter: blur(2px);
|
backdrop-filter: blur(2px);
|
||||||
@@ -362,6 +363,7 @@ body {
|
|||||||
font-size: 90%;
|
font-size: 90%;
|
||||||
bottom: 0.5em;
|
bottom: 0.5em;
|
||||||
-webkit-line-clamp: 2;
|
-webkit-line-clamp: 2;
|
||||||
|
line-clamp: 2;
|
||||||
max-height: 3.3em;
|
max-height: 3.3em;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
width: 98vw !important;
|
width: 98vw !important;
|
||||||
@@ -641,8 +643,8 @@ body {
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 1em;
|
width: 1.2em;
|
||||||
height: 1em;
|
height: 1.2em;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transition: background 0.3s, color 0.3s;
|
transition: background 0.3s, color 0.3s;
|
||||||
@@ -655,8 +657,8 @@ body {
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 1em;
|
width: 1.2em;
|
||||||
height: 1em;
|
height: 1.2em;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transition: background 0.3s, color 0.3s;
|
transition: background 0.3s, color 0.3s;
|
||||||
@@ -678,6 +680,7 @@ body {
|
|||||||
border-top-right-radius: 1em;
|
border-top-right-radius: 1em;
|
||||||
border-top-left-radius: 1em;
|
border-top-left-radius: 1em;
|
||||||
-webkit-mask-image: linear-gradient(0deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.25) 3%, rgba(0, 0, 0, 0.5) 7%, rgba(0, 0, 0, 0.75) 15%, rgba(0, 0, 0, 0.9) 25%, rgba(0, 0, 0, 1) 35%, rgba(0, 0, 0, 1) 100%);
|
-webkit-mask-image: linear-gradient(0deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.25) 3%, rgba(0, 0, 0, 0.5) 7%, rgba(0, 0, 0, 0.75) 15%, rgba(0, 0, 0, 0.9) 25%, rgba(0, 0, 0, 1) 35%, rgba(0, 0, 0, 1) 100%);
|
||||||
|
mask-image: linear-gradient(0deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.25) 3%, rgba(0, 0, 0, 0.5) 7%, rgba(0, 0, 0, 0.75) 15%, rgba(0, 0, 0, 0.9) 25%, rgba(0, 0, 0, 1) 35%, rgba(0, 0, 0, 1) 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-container::after {
|
.text-container::after {
|
||||||
@@ -693,6 +696,7 @@ body {
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
backdrop-filter: blur(0px);
|
backdrop-filter: blur(0px);
|
||||||
-webkit-mask-image: linear-gradient(0deg, rgb(0% 0% 0% / 0.98) 0%, rgb(0% 0% 0% / 0.9705847873975829) 6.25%, rgb(0% 0% 0% / 0.9427009709305305) 12.5%, rgb(0% 0% 0% / 0.8974201100282472) 18.75%, rgb(0% 0% 0% / 0.8364823227814083) 25%, rgb(0% 0% 0% / 0.7622294141796051) 31.25%, rgb(0% 0% 0% / 0.6775148818588941) 37.5%, rgb(0% 0% 0% / 0.5855942577879029) 43.75%, rgb(0% 0% 0% / 0.49000000000000005) 50%, rgb(0% 0% 0% / 0.39440574221209723) 56.25%, rgb(0% 0% 0% / 0.3024851181411061) 62.5%, rgb(0% 0% 0% / 0.217770585820395) 68.75%, rgb(0% 0% 0% / 0.14351767721859177) 75%, rgb(0% 0% 0% / 0.0825798899717528) 81.25%, rgb(0% 0% 0% / 0.03729902906946947) 87.5%, rgb(0% 0% 0% / 0.009415212602417067) 93.75%, rgb(0% 0% 0% / 0) 100%);
|
-webkit-mask-image: linear-gradient(0deg, rgb(0% 0% 0% / 0.98) 0%, rgb(0% 0% 0% / 0.9705847873975829) 6.25%, rgb(0% 0% 0% / 0.9427009709305305) 12.5%, rgb(0% 0% 0% / 0.8974201100282472) 18.75%, rgb(0% 0% 0% / 0.8364823227814083) 25%, rgb(0% 0% 0% / 0.7622294141796051) 31.25%, rgb(0% 0% 0% / 0.6775148818588941) 37.5%, rgb(0% 0% 0% / 0.5855942577879029) 43.75%, rgb(0% 0% 0% / 0.49000000000000005) 50%, rgb(0% 0% 0% / 0.39440574221209723) 56.25%, rgb(0% 0% 0% / 0.3024851181411061) 62.5%, rgb(0% 0% 0% / 0.217770585820395) 68.75%, rgb(0% 0% 0% / 0.14351767721859177) 75%, rgb(0% 0% 0% / 0.0825798899717528) 81.25%, rgb(0% 0% 0% / 0.03729902906946947) 87.5%, rgb(0% 0% 0% / 0.009415212602417067) 93.75%, rgb(0% 0% 0% / 0) 100%);
|
||||||
|
mask-image: linear-gradient(0deg, rgb(0% 0% 0% / 0.98) 0%, rgb(0% 0% 0% / 0.9705847873975829) 6.25%, rgb(0% 0% 0% / 0.9427009709305305) 12.5%, rgb(0% 0% 0% / 0.8974201100282472) 18.75%, rgb(0% 0% 0% / 0.8364823227814083) 25%, rgb(0% 0% 0% / 0.7622294141796051) 31.25%, rgb(0% 0% 0% / 0.6775148818588941) 37.5%, rgb(0% 0% 0% / 0.5855942577879029) 43.75%, rgb(0% 0% 0% / 0.49000000000000005) 50%, rgb(0% 0% 0% / 0.39440574221209723) 56.25%, rgb(0% 0% 0% / 0.3024851181411061) 62.5%, rgb(0% 0% 0% / 0.217770585820395) 68.75%, rgb(0% 0% 0% / 0.14351767721859177) 75%, rgb(0% 0% 0% / 0.0825798899717528) 81.25%, rgb(0% 0% 0% / 0.03729902906946947) 87.5%, rgb(0% 0% 0% / 0.009415212602417067) 93.75%, rgb(0% 0% 0% / 0) 100%);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -885,6 +889,7 @@ body {
|
|||||||
font-size: 133%;
|
font-size: 133%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
.backdrop {}
|
.backdrop {}
|
||||||
|
|
||||||
.age-rating {}
|
.age-rating {}
|
||||||
@@ -896,6 +901,7 @@ body {
|
|||||||
.genres {}
|
.genres {}
|
||||||
|
|
||||||
.lorem-ipsum {}
|
.lorem-ipsum {}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 3000px) {
|
@media (min-width: 3000px) {
|
||||||
@@ -903,6 +909,7 @@ body {
|
|||||||
font-size: 200%;
|
font-size: 200%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
.age-rating {}
|
.age-rating {}
|
||||||
|
|
||||||
.skip-button {}
|
.skip-button {}
|
||||||
@@ -914,6 +921,7 @@ body {
|
|||||||
.genres {}
|
.genres {}
|
||||||
|
|
||||||
.lorem-ipsum {}
|
.lorem-ipsum {}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
#video-overlay {
|
#video-overlay {
|
||||||
|
Reference in New Issue
Block a user