mirror of
https://github.com/ajayyy/SponsorBlock.git
synced 2025-12-07 12:07:11 +03:00
Add new workaround for improving skipping precision on Firefox
This commit is contained in:
@@ -71,12 +71,14 @@ let channelIDInfo: ChannelIDInfo;
|
|||||||
// Locked Categories in this tab, like: ["sponsor","intro","outro"]
|
// Locked Categories in this tab, like: ["sponsor","intro","outro"]
|
||||||
let lockedCategories: Category[] = [];
|
let lockedCategories: Category[] = [];
|
||||||
// Used to calculate a more precise "virtual" video time
|
// Used to calculate a more precise "virtual" video time
|
||||||
let lastKnownVideoTime: { videoTime: number; preciseTime: number } = {
|
const lastKnownVideoTime: { videoTime: number; preciseTime: number; fromPause: boolean; approximateDelay: number } = {
|
||||||
videoTime: null,
|
videoTime: null,
|
||||||
preciseTime: null
|
preciseTime: null,
|
||||||
|
fromPause: false,
|
||||||
|
approximateDelay: null,
|
||||||
};
|
};
|
||||||
// It resumes with a slightly later time on chromium
|
// It resumes with a slightly later time on chromium
|
||||||
let lastTimeFromWaitingEvent = null;
|
let lastTimeFromWaitingEvent: number = null;
|
||||||
const lastNextChapterKeybind = {
|
const lastNextChapterKeybind = {
|
||||||
time: 0,
|
time: 0,
|
||||||
date: 0
|
date: 0
|
||||||
@@ -87,6 +89,7 @@ const lastNextChapterKeybind = {
|
|||||||
// Skips are canceled every seeking event
|
// Skips are canceled every seeking event
|
||||||
let currentSkipSchedule: NodeJS.Timeout = null;
|
let currentSkipSchedule: NodeJS.Timeout = null;
|
||||||
let currentSkipInterval: NodeJS.Timeout = null;
|
let currentSkipInterval: NodeJS.Timeout = null;
|
||||||
|
let currentVirtualTimeInterval: NodeJS.Timeout = null;
|
||||||
|
|
||||||
/** Has the sponsor been skipped */
|
/** Has the sponsor been skipped */
|
||||||
let sponsorSkipped: boolean[] = [];
|
let sponsorSkipped: boolean[] = [];
|
||||||
@@ -600,6 +603,7 @@ function startSponsorSchedule(includeIntersectingSegments = false, currentTime?:
|
|||||||
if (currentTime === undefined || currentTime === null) {
|
if (currentTime === undefined || currentTime === null) {
|
||||||
currentTime = getVirtualTime();
|
currentTime = getVirtualTime();
|
||||||
}
|
}
|
||||||
|
clearWaitingTime();
|
||||||
lastTimeFromWaitingEvent = null;
|
lastTimeFromWaitingEvent = null;
|
||||||
|
|
||||||
updateActiveSegment(currentTime);
|
updateActiveSegment(currentTime);
|
||||||
@@ -704,11 +708,23 @@ function startSponsorSchedule(includeIntersectingSegments = false, currentTime?:
|
|||||||
// Use interval instead of timeout near the end to combat imprecise video time
|
// Use interval instead of timeout near the end to combat imprecise video time
|
||||||
const startIntervalTime = performance.now();
|
const startIntervalTime = performance.now();
|
||||||
const startVideoTime = Math.max(currentTime, video.currentTime);
|
const startVideoTime = Math.max(currentTime, video.currentTime);
|
||||||
|
|
||||||
|
let startWaitingForReportedTimeToChange = true;
|
||||||
|
const reportedVideoTimeAtStart = video.currentTime;
|
||||||
logDebug(`Starting setInterval skipping ${video.currentTime} to skip at ${skipTime[0]}`);
|
logDebug(`Starting setInterval skipping ${video.currentTime} to skip at ${skipTime[0]}`);
|
||||||
|
|
||||||
currentSkipInterval = setInterval(() => {
|
currentSkipInterval = setInterval(() => {
|
||||||
|
// Estimate delay, but only take the current time right after a change
|
||||||
|
// Current time remains the same for many "frames" on Firefox
|
||||||
|
if (utils.isFirefox() && !lastKnownVideoTime.fromPause && startWaitingForReportedTimeToChange
|
||||||
|
&& reportedVideoTimeAtStart !== video.currentTime) {
|
||||||
|
startWaitingForReportedTimeToChange = false;
|
||||||
|
const delay = getVirtualTime() - video.currentTime;
|
||||||
|
if (delay > 0) lastKnownVideoTime.approximateDelay = delay;
|
||||||
|
}
|
||||||
|
|
||||||
const intervalDuration = performance.now() - startIntervalTime;
|
const intervalDuration = performance.now() - startIntervalTime;
|
||||||
if (intervalDuration >= delayTime || video.currentTime >= skipTime[0]) {
|
if (intervalDuration + skipBuffer * 1000 >= delayTime || video.currentTime >= skipTime[0]) {
|
||||||
clearInterval(currentSkipInterval);
|
clearInterval(currentSkipInterval);
|
||||||
if (!utils.isFirefox() && !video.muted) {
|
if (!utils.isFirefox() && !video.muted) {
|
||||||
// Workaround for more accurate skipping on Chromium
|
// Workaround for more accurate skipping on Chromium
|
||||||
@@ -716,7 +732,7 @@ function startSponsorSchedule(includeIntersectingSegments = false, currentTime?:
|
|||||||
video.muted = false;
|
video.muted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
skippingFunction(Math.max(video.currentTime, startVideoTime + video.playbackRate * intervalDuration / 1000));
|
skippingFunction(Math.max(video.currentTime, startVideoTime + video.playbackRate * Math.max(delayTime, intervalDuration) / 1000));
|
||||||
}
|
}
|
||||||
}, 1);
|
}, 1);
|
||||||
} else {
|
} else {
|
||||||
@@ -729,11 +745,11 @@ function startSponsorSchedule(includeIntersectingSegments = false, currentTime?:
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getVirtualTime(): number {
|
function getVirtualTime(): number {
|
||||||
const virtualTime = lastTimeFromWaitingEvent ?? (lastKnownVideoTime.videoTime ?
|
const virtualTime = lastTimeFromWaitingEvent ?? (lastKnownVideoTime.videoTime !== null ?
|
||||||
(performance.now() - lastKnownVideoTime.preciseTime) * video.playbackRate / 1000 + lastKnownVideoTime.videoTime : null);
|
(performance.now() - lastKnownVideoTime.preciseTime) * video.playbackRate / 1000 + lastKnownVideoTime.videoTime : null);
|
||||||
|
|
||||||
if (Config.config.useVirtualTime && !utils.isFirefox() && !isSafari() && virtualTime
|
if (Config.config.useVirtualTime && !isSafari() && virtualTime
|
||||||
&& Math.abs(virtualTime - video.currentTime) < 0.6 && video.currentTime !== 0) {
|
&& Math.abs(virtualTime - video.currentTime) < 0.2 && video.currentTime !== 0) {
|
||||||
return virtualTime;
|
return virtualTime;
|
||||||
} else {
|
} else {
|
||||||
return video.currentTime;
|
return video.currentTime;
|
||||||
@@ -878,13 +894,15 @@ function setupVideoListeners() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
video.addEventListener('seeking', () => {
|
video.addEventListener('seeking', () => {
|
||||||
|
lastKnownVideoTime.fromPause = false;
|
||||||
|
|
||||||
if (!video.paused){
|
if (!video.paused){
|
||||||
// Reset lastCheckVideoTime
|
// Reset lastCheckVideoTime
|
||||||
lastCheckTime = Date.now();
|
lastCheckTime = Date.now();
|
||||||
lastCheckVideoTime = video.currentTime;
|
lastCheckVideoTime = video.currentTime;
|
||||||
|
|
||||||
updateVirtualTime();
|
updateVirtualTime();
|
||||||
lastTimeFromWaitingEvent = null;
|
clearWaitingTime();
|
||||||
|
|
||||||
startSponsorSchedule();
|
startSponsorSchedule();
|
||||||
} else {
|
} else {
|
||||||
@@ -897,36 +915,38 @@ function setupVideoListeners() {
|
|||||||
});
|
});
|
||||||
video.addEventListener('ratechange', () => {
|
video.addEventListener('ratechange', () => {
|
||||||
updateVirtualTime();
|
updateVirtualTime();
|
||||||
lastTimeFromWaitingEvent = null;
|
clearWaitingTime();
|
||||||
|
|
||||||
startSponsorSchedule();
|
startSponsorSchedule();
|
||||||
});
|
});
|
||||||
// Used by videospeed extension (https://github.com/igrigorik/videospeed/pull/740)
|
// Used by videospeed extension (https://github.com/igrigorik/videospeed/pull/740)
|
||||||
video.addEventListener('videoSpeed_ratechange', () => {
|
video.addEventListener('videoSpeed_ratechange', () => {
|
||||||
updateVirtualTime();
|
updateVirtualTime();
|
||||||
lastTimeFromWaitingEvent = null;
|
clearWaitingTime();
|
||||||
|
|
||||||
startSponsorSchedule();
|
startSponsorSchedule();
|
||||||
});
|
});
|
||||||
const paused = () => {
|
const stoppedPlayback = () => {
|
||||||
// Reset lastCheckVideoTime
|
// Reset lastCheckVideoTime
|
||||||
lastCheckVideoTime = -1;
|
lastCheckVideoTime = -1;
|
||||||
lastCheckTime = 0;
|
lastCheckTime = 0;
|
||||||
|
|
||||||
lastKnownVideoTime = {
|
lastKnownVideoTime.videoTime = null;
|
||||||
videoTime: null,
|
lastKnownVideoTime.preciseTime = null;
|
||||||
preciseTime: null
|
updateWaitingTime();
|
||||||
}
|
|
||||||
lastTimeFromWaitingEvent = video.currentTime;
|
|
||||||
|
|
||||||
cancelSponsorSchedule();
|
cancelSponsorSchedule();
|
||||||
};
|
};
|
||||||
video.addEventListener('pause', () => paused());
|
video.addEventListener('pause', () => {
|
||||||
|
lastKnownVideoTime.fromPause = true;
|
||||||
|
|
||||||
|
stoppedPlayback();
|
||||||
|
});
|
||||||
video.addEventListener('waiting', () => {
|
video.addEventListener('waiting', () => {
|
||||||
logDebug("[SB] Not skipping due to buffering");
|
logDebug("[SB] Not skipping due to buffering");
|
||||||
startedWaiting = true;
|
startedWaiting = true;
|
||||||
|
|
||||||
paused();
|
stoppedPlayback();
|
||||||
});
|
});
|
||||||
|
|
||||||
startSponsorSchedule();
|
startSponsorSchedule();
|
||||||
@@ -934,10 +954,43 @@ function setupVideoListeners() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateVirtualTime() {
|
function updateVirtualTime() {
|
||||||
lastKnownVideoTime = {
|
if (currentVirtualTimeInterval) clearInterval(currentVirtualTimeInterval);
|
||||||
videoTime: video.currentTime,
|
|
||||||
preciseTime: performance.now()
|
lastKnownVideoTime.videoTime = video.currentTime;
|
||||||
};
|
lastKnownVideoTime.preciseTime = performance.now();
|
||||||
|
|
||||||
|
// If on Firefox, wait for the second time change (time remains fixed for many "frames" for privacy reasons)
|
||||||
|
if (utils.isFirefox()) {
|
||||||
|
let count = 0;
|
||||||
|
let lastTime = lastKnownVideoTime.videoTime;
|
||||||
|
if (lastKnownVideoTime.fromPause) {
|
||||||
|
currentVirtualTimeInterval = setInterval(() => {
|
||||||
|
if (lastTime !== video.currentTime) {
|
||||||
|
count++;
|
||||||
|
lastTime = video.currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count > 1) {
|
||||||
|
const delay = lastKnownVideoTime.fromPause && lastKnownVideoTime.approximateDelay ?
|
||||||
|
lastKnownVideoTime.approximateDelay : 0;
|
||||||
|
|
||||||
|
lastKnownVideoTime.videoTime = video.currentTime + delay;
|
||||||
|
lastKnownVideoTime.preciseTime = performance.now();
|
||||||
|
|
||||||
|
clearInterval(currentVirtualTimeInterval);
|
||||||
|
currentVirtualTimeInterval = null;
|
||||||
|
}
|
||||||
|
}, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateWaitingTime(): void {
|
||||||
|
lastTimeFromWaitingEvent = video.currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearWaitingTime(): void {
|
||||||
|
lastTimeFromWaitingEvent = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupSkipButtonControlBar() {
|
function setupSkipButtonControlBar() {
|
||||||
|
|||||||
Reference in New Issue
Block a user