..
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 token = 'YOURAPIKEYHERE'; // Your Jellyfin API key
|
||||
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 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 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 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 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 currentLocation = window.top.location.href;
|
||||
let movieList = [], currentMovieIndex = 0;
|
||||
let previousMovies = [];
|
||||
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
|
||||
//function fetchSponsorBlockOutro(videoId) {
|
||||
const fetchSponsorBlockOutro = (videoId) => {
|
||||
// @deprecated
|
||||
const fetchSponsorBlockOutroOLD = (videoId) => {
|
||||
return fetch(`https://sponsor.ajay.app/api/skipSegments?videoID=${videoId}&category=outro`)
|
||||
.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 => {
|
||||
console.error('Error fetching SponsorBlock data:', error);
|
||||
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
|
||||
let monitorOutroInterval = null; // Global interval variable
|
||||
function monitorOutro(player, outroSegment) {
|
||||
const interval = setInterval(() => {
|
||||
if (monitorOutroInterval) { // Clear the interval if it's already running
|
||||
clearInterval(monitorOutroInterval);
|
||||
}
|
||||
|
||||
monitorOutroInterval = setInterval(() => {
|
||||
if (!outroSegment || !player) {
|
||||
clearInterval(interval);
|
||||
console.log('Invalid outro segment or player not initialized');
|
||||
clearInterval(monitorOutroInterval);
|
||||
return;
|
||||
}
|
||||
|
||||
const currentTime = player.getCurrentTime();
|
||||
if (currentTime >= outroSegment[0] && currentTime < outroSegment[1]) {
|
||||
clearInterval(interval);
|
||||
clearInterval(monitorOutroInterval);
|
||||
player.stopVideo(); // stop video
|
||||
setTimeout(fetchRandomMovie, 100); // fetch next movie
|
||||
}
|
||||
@@ -247,13 +292,11 @@ const createSlideElement = (movie, hasVideo = false) => {
|
||||
width: '100%',
|
||||
videoId,
|
||||
playerVars: {
|
||||
mute: 0, // Change to start the video muted MARK: set muted, not officaly refreneced by youtube API, but working...
|
||||
controls: 0, // Hide the controls
|
||||
mute: isMuted ? 1 : 0, // CHeck if the video should start muted
|
||||
controls: disableTrailerControls ? 0 : 1, // Hide the controls
|
||||
disablekb: 1, // Disable keyboard controls
|
||||
fs: 1, // Enavle fullscreen
|
||||
rel: 0, // Disable related videos
|
||||
modestbranding: 1, // Hide the YouTube logo
|
||||
showinfo: 0, // Hide the video title
|
||||
iv_load_policy: 3, // Disable annotations
|
||||
},
|
||||
events: {
|
||||
'onReady': event => {
|
||||
@@ -266,7 +309,7 @@ const createSlideElement = (movie, hasVideo = false) => {
|
||||
console.log('No outro segment found/provided');
|
||||
}
|
||||
}).catch(error => {
|
||||
console.error('Error fetching SponsorBlock outro segment:', error);
|
||||
console.error('Error reading SponsorBlock outro segment:', error);
|
||||
});
|
||||
}
|
||||
if (trailerMaxLength > 0) {
|
||||
@@ -283,7 +326,7 @@ const createSlideElement = (movie, hasVideo = false) => {
|
||||
if (isMuted) {
|
||||
event.target.setVolume(0); // Mute the video if the setting is MuteOn
|
||||
} else {
|
||||
event.target.setVolume(4);
|
||||
event.target.setVolume(unmutedVolume); // Set the volume, value between 0 and 100
|
||||
}
|
||||
event.target.playVideo();
|
||||
},
|
||||
@@ -320,6 +363,7 @@ const createSlideElement = (movie, hasVideo = false) => {
|
||||
'onError': () => {
|
||||
console.error(`YouTube prevented playback of '${movie.Name}'`);
|
||||
if (player) {
|
||||
clearInterval(monitorOutroInterval);
|
||||
player.destroy();
|
||||
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 {
|
||||
console.log(`Trailer disabled for '${movie.Name}'`);
|
||||
startSlideChangeTimer();
|
||||
}
|
||||
|
||||
|
@@ -1,12 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<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>
|
||||
<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">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="slides-container"></div>
|
||||
<div id="video-overlay" style="display: none;">
|
||||
@@ -18,4 +21,5 @@
|
||||
<script src="script.js"></script>
|
||||
<script src="https://www.youtube.com/iframe_api"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
@@ -208,6 +208,7 @@ body {
|
||||
max-width: 96vw;
|
||||
opacity: 1;
|
||||
-webkit-line-clamp: 2;
|
||||
line-clamp: 2;
|
||||
max-height: 7.8em;
|
||||
text-align: center;
|
||||
}
|
||||
@@ -307,17 +308,17 @@ body {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.slide:hover .clickable-overlay {}
|
||||
/*.slide:hover .clickable-overlay {}*/
|
||||
|
||||
.slide:hover .clickable-overlay::before {
|
||||
opacity: 0;
|
||||
backdrop-filter: blur(0px);
|
||||
}
|
||||
|
||||
/*
|
||||
.slide:hover .logo {}
|
||||
|
||||
.slide:hover .plot {}
|
||||
|
||||
*/
|
||||
.slide:hover .lorem-ipsum::before {
|
||||
opacity: 1;
|
||||
backdrop-filter: blur(2px);
|
||||
@@ -362,6 +363,7 @@ body {
|
||||
font-size: 90%;
|
||||
bottom: 0.5em;
|
||||
-webkit-line-clamp: 2;
|
||||
line-clamp: 2;
|
||||
max-height: 3.3em;
|
||||
overflow: hidden;
|
||||
width: 98vw !important;
|
||||
@@ -641,8 +643,8 @@ body {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
width: 1.2em;
|
||||
height: 1.2em;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
transition: background 0.3s, color 0.3s;
|
||||
@@ -655,8 +657,8 @@ body {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
width: 1.2em;
|
||||
height: 1.2em;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
transition: background 0.3s, color 0.3s;
|
||||
@@ -678,6 +680,7 @@ body {
|
||||
border-top-right-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%);
|
||||
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 {
|
||||
@@ -693,6 +696,7 @@ body {
|
||||
opacity: 1;
|
||||
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%);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -885,6 +889,7 @@ body {
|
||||
font-size: 133%;
|
||||
}
|
||||
|
||||
/*
|
||||
.backdrop {}
|
||||
|
||||
.age-rating {}
|
||||
@@ -896,6 +901,7 @@ body {
|
||||
.genres {}
|
||||
|
||||
.lorem-ipsum {}
|
||||
*/
|
||||
}
|
||||
|
||||
@media (min-width: 3000px) {
|
||||
@@ -903,6 +909,7 @@ body {
|
||||
font-size: 200%;
|
||||
}
|
||||
|
||||
/*
|
||||
.age-rating {}
|
||||
|
||||
.skip-button {}
|
||||
@@ -914,6 +921,7 @@ body {
|
||||
.genres {}
|
||||
|
||||
.lorem-ipsum {}
|
||||
*/
|
||||
}
|
||||
|
||||
#video-overlay {
|
||||
|
Reference in New Issue
Block a user