Fix seek issue and improve button animation smoothness (#209)
This commit is contained in:
parent
4081c72edd
commit
009917b2e1
@ -100,6 +100,9 @@ introSkipper.d = function (msg) {
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: opacity 0.3s ease-in, transform 0.3s ease-out;
|
transition: opacity 0.3s ease-in, transform 0.3s ease-out;
|
||||||
}
|
}
|
||||||
|
#skipIntro.show .emby-button {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
#skipIntro .emby-button:hover,
|
#skipIntro .emby-button:hover,
|
||||||
#skipIntro .emby-button:focus {
|
#skipIntro .emby-button:focus {
|
||||||
background-color: rgba(var(--accent),0.7);
|
background-color: rgba(var(--accent),0.7);
|
||||||
@ -197,9 +200,8 @@ introSkipper.videoPositionChanged = function () {
|
|||||||
const segment = introSkipper.getCurrentSegment(introSkipper.videoPlayer.currentTime);
|
const segment = introSkipper.getCurrentSegment(introSkipper.videoPlayer.currentTime);
|
||||||
switch (segment.SegmentType) {
|
switch (segment.SegmentType) {
|
||||||
case "None":
|
case "None":
|
||||||
if (embyButton.style.opacity === '0') return;
|
if (!skipButton.classList.contains('show')) return;
|
||||||
|
skipButton.classList.remove('show');
|
||||||
embyButton.style.opacity = '0';
|
|
||||||
embyButton.addEventListener("transitionend", () => {
|
embyButton.addEventListener("transitionend", () => {
|
||||||
skipButton.classList.add("hide");
|
skipButton.classList.add("hide");
|
||||||
if (tvLayout) {
|
if (tvLayout) {
|
||||||
@ -216,14 +218,16 @@ introSkipper.videoPositionChanged = function () {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!skipButton.classList.contains("hide")) return;
|
if (!skipButton.classList.contains("hide")) return;
|
||||||
|
requestAnimationFrame(() => {
|
||||||
skipButton.classList.remove("hide");
|
skipButton.classList.remove("hide");
|
||||||
embyButton.style.opacity = '1';
|
requestAnimationFrame(() => {
|
||||||
|
skipButton.classList.add('show');
|
||||||
if (tvLayout) {
|
if (tvLayout) {
|
||||||
introSkipper.overrideBlur(embyButton);
|
introSkipper.overrideBlur(embyButton);
|
||||||
embyButton.focus({ focusVisible: true });
|
embyButton.focus({ focusVisible: true });
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
introSkipper.throttle = function (func, limit) {
|
introSkipper.throttle = function (func, limit) {
|
||||||
let inThrottle;
|
let inThrottle;
|
||||||
@ -245,34 +249,44 @@ introSkipper.doSkip = introSkipper.throttle(async function () {
|
|||||||
console.warn("[intro skipper] doSkip() called without an active segment");
|
console.warn("[intro skipper] doSkip() called without an active segment");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const currentSrc = introSkipper.videoPlayer.currentSrc;
|
||||||
|
const controller = new AbortController();
|
||||||
|
const signal = controller.signal;
|
||||||
const seekToSegmentEnd = () => new Promise((resolve) => {
|
const seekToSegmentEnd = () => new Promise((resolve) => {
|
||||||
const onSeeked = () => {
|
const onSeeked = () => requestAnimationFrame(resolve);
|
||||||
setTimeout(() => {
|
introSkipper.videoPlayer.addEventListener('seeked', onSeeked, { once: true, signal });
|
||||||
introSkipper.allowEnter = true;
|
|
||||||
resolve();
|
|
||||||
}, 50); // Wait 50ms after seek completes
|
|
||||||
};
|
|
||||||
introSkipper.videoPlayer.addEventListener('seeked', onSeeked, { once: true });
|
|
||||||
introSkipper.videoPlayer.currentTime = segment.IntroEnd;
|
introSkipper.videoPlayer.currentTime = segment.IntroEnd;
|
||||||
});
|
});
|
||||||
|
const nextEpisodeLoaded = () => new Promise(resolve => {
|
||||||
|
const onLoadStart = () => resolve(true);
|
||||||
|
const timeoutId = setTimeout(() => resolve(false), 500);
|
||||||
|
introSkipper.videoPlayer.addEventListener('loadstart', onLoadStart, { signal });
|
||||||
|
signal.addEventListener('abort', () => clearTimeout(timeoutId));
|
||||||
|
});
|
||||||
// Disable keydown events
|
// Disable keydown events
|
||||||
introSkipper.allowEnter = false;
|
introSkipper.allowEnter = false;
|
||||||
// Check if the segment is "Credits" and skipping would leave less than 3 seconds of video
|
try {
|
||||||
if (segment.SegmentType === "Credits" && introSkipper.videoPlayer.duration - segment.IntroEnd < 3) {
|
// Check if the segment is "Credits" and skipping would leave less than 3 seconds of video
|
||||||
// Simulate 'N' key press to go to the next episode
|
if (segment.SegmentType === "Credits" && introSkipper.videoPlayer.duration - segment.IntroEnd < 3) {
|
||||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'N', shiftKey: true, bubbles: true }));
|
// Simulate 'N' key press to go to the next episode
|
||||||
// Check if the next episode actually starts loading
|
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'N', shiftKey: true, bubbles: true }));
|
||||||
const nextEpisodeLoaded = await Promise.race([
|
// Check if the next episode actually starts loading
|
||||||
new Promise(resolve => introSkipper.videoPlayer.addEventListener('loadstart', () => resolve(true), { once: true })),
|
const loaded = await nextEpisodeLoaded();
|
||||||
new Promise(resolve => setTimeout(() => resolve(false), 300))
|
// If the next episode didn't load, just seek to the end of the current segment
|
||||||
]);
|
if (!loaded) {
|
||||||
// If the next episode didn't load, just seek to the end of the current segment
|
await new Promise(resolve => setTimeout(resolve, 100)); // Short delay
|
||||||
if (!nextEpisodeLoaded) await seekToSegmentEnd();
|
if (introSkipper.videoPlayer.currentSrc === currentSrc) {
|
||||||
else introSkipper.allowEnter = true;
|
await seekToSegmentEnd();
|
||||||
return;
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Default behavior: seek to the end of the current segment
|
||||||
|
await seekToSegmentEnd();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
introSkipper.allowEnter = true; // Always re-enable keydown events
|
||||||
|
controller.abort(); // Cleanup any remaining listeners
|
||||||
}
|
}
|
||||||
// Default behavior: seek to the end of the current segment
|
|
||||||
await seekToSegmentEnd();
|
|
||||||
}, 3000);
|
}, 3000);
|
||||||
/** Tests if an element with the provided selector exists. */
|
/** Tests if an element with the provided selector exists. */
|
||||||
introSkipper.testElement = function (selector) { return document.querySelector(selector); }
|
introSkipper.testElement = function (selector) { return document.querySelector(selector); }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user