Switched to new skipping mechanic

This commit is contained in:
Ajay Ramachandran
2020-02-18 18:29:02 -05:00
parent cd58f6bc73
commit 5b2a0feccf

View File

@@ -15,11 +15,17 @@ utils.wait(() => Config.config !== null, 5000, 10).then(addCSS);
var sponsorDataFound = false;
var previousVideoID = null;
//the actual sponsorTimes if loaded and UUIDs associated with them
var sponsorTimes = null;
var sponsorTimes: number[][] = null;
var UUIDs = [];
//what video id are these sponsors for
var sponsorVideoID = null;
// Skips are scheduled to ensure precision.
// Skips are rescheduled every seeked event.
// Skips are canceled every seeking event
var currentSkipSchedule: NodeJS.Timeout = null;
var seekListenerSetUp = false
//these are sponsors that have been downvoted
var hiddenSponsorTimes = [];
@@ -416,6 +422,39 @@ function durationChangeListener() {
updatePreviewBar();
}
function cancelSponsorSchedule(): void {
if (currentSkipSchedule !== null) {
clearTimeout(currentSkipSchedule);
}
}
/**
*
* @param currentTime Optional if you don't want to use the actual current time
*/
function startSponsorSchedule(currentTime?: number): void {
cancelSponsorSchedule();
if (Config.config.disableSkipping) return;
if (currentTime === undefined) currentTime = video.currentTime;
let skipInfo = getNextSkipIndex(currentTime);
let skipStartTime = skipInfo.array[skipInfo.index][0];
let timeUntilSponsor = skipStartTime - currentTime;
currentSkipSchedule = setTimeout(() => {
if (video.currentTime >= skipStartTime) {
skipToTime(video, skipInfo.index, skipInfo.array, skipInfo.openNotice);
startSponsorSchedule();
} else {
startSponsorSchedule();
}
}, timeUntilSponsor * 1000 * (1 / video.playbackRate));
}
function sponsorsLookup(id: string, channelIDPromise?) {
video = document.querySelector('video') // Youtube video player
//there is no video here
@@ -431,6 +470,16 @@ function sponsorsLookup(id: string, channelIDPromise?) {
video.addEventListener('durationchange', durationChangeListener);
}
if (!seekListenerSetUp && !Config.config.disableSkipping) {
seekListenerSetUp = true;
video.addEventListener('seeked', () => startSponsorSchedule());
video.addEventListener('play', () => startSponsorSchedule());
video.addEventListener('ratechange', () => startSponsorSchedule());
video.addEventListener('seeking', cancelSponsorSchedule);
video.addEventListener('pause', cancelSponsorSchedule);
}
if (channelIDPromise !== undefined) {
if (channelIDPromise.isFulfilled) {
whitelistCheck();
@@ -481,6 +530,19 @@ function sponsorsLookup(id: string, channelIDPromise?) {
UUIDs = smallUUIDs;
}
// See if there are any zero second sponsors
let zeroSecondSponsor = false;
for (const time of sponsorTimes) {
if (time[0] <= 0) {
zeroSecondSponsor = true;
break;
}
}
if (zeroSecondSponsor) {
startSponsorSchedule(0);
}
// Reset skip save
sponsorSkipped = [];
@@ -528,13 +590,6 @@ function sponsorsLookup(id: string, channelIDPromise?) {
sponsorLookupRetries++;
}
});
//add the event to run on the videos "ontimeupdate"
if (!Config.config.disableSkipping) {
video.ontimeupdate = function () {
sponsorCheck();
};
}
}
function getYouTubeVideoID(url: string) {
@@ -673,76 +728,45 @@ function whitelistCheck() {
}
}
//video skipping
function sponsorCheck() {
if (Config.config.disableSkipping) {
// Make sure this isn't called again
video.ontimeupdate = null;
return;
} else if (channelWhitelisted) {
return;
/**
* Returns info about the next upcoming sponsor skip
*/
function getNextSkipIndex(currentTime: number): {array: number[][], index: number, openNotice: boolean} {
let sponsorStartTimes = getStartTimes(sponsorTimes);
let sponsorStartTimesAfterCurrentTime = getStartTimes(sponsorTimes, currentTime, true);
let minSponsorTimeIndex = sponsorStartTimes.indexOf(Math.min(...sponsorStartTimesAfterCurrentTime));
// TOOD: support preview sponsors
return {
array: sponsorTimes,
index: minSponsorTimeIndex,
openNotice: true
};
}
// Don't skip right after duration change (the time resets to zero) 400ms
if (Date.now() - lastDurationChange < 400000 && lastTime > 1) return;
/**
* Gets just the start times from a sponsor times array.
* Optionally specify a minimum
*
* @param sponsorTimes
* @param minimum
* @param hideHiddenSponsors
*/
function getStartTimes(sponsorTimes: number[][], minimum?: number, hideHiddenSponsors: boolean = false): number[] {
let startTimes: number[] = [];
let skipHappened = false;
if (sponsorTimes != null) {
//see if any sponsor start time was just passed
for (let i = 0; i < sponsorTimes.length; i++) {
//if something was skipped
if (checkSponsorTime(sponsorTimes, i, true)) {
skipHappened = true;
break;
}
}
}
if (!skipHappened) {
//check for the "preview" sponsors (currently edited by this user)
for (let i = 0; i < sponsorTimesSubmitting.length; i++) {
//must be a finished sponsor and be valid
if (sponsorTimesSubmitting[i].length > 1 && sponsorTimesSubmitting[i][1] > sponsorTimesSubmitting[i][0]) {
checkSponsorTime(sponsorTimesSubmitting, i, false);
}
}
}
//don't keep track until they are loaded in
if (sponsorTimes !== null || sponsorTimesSubmitting.length > 0) {
lastTime = video.currentTime;
if ((minimum === undefined || sponsorTimes[i][0] >= minimum) && (!hideHiddenSponsors || !hiddenSponsorTimes.includes(i))) {
startTimes.push(sponsorTimes[i][0]);
}
}
function checkSponsorTime(sponsorTimes, index, openNotice): boolean {
//this means part of the video was just skipped
if (Math.abs(video.currentTime - lastTime) > 1 && lastTime != -1) {
//make lastTime as if the video was playing normally
lastTime = video.currentTime - 0.0001;
return startTimes;
}
if (checkIfTimeToSkip(video.currentTime, sponsorTimes[index][0], sponsorTimes[index][1]) && !hiddenSponsorTimes.includes(index)) {
//skip it
skipToTime(video, index, sponsorTimes, openNotice);
//something was skipped
return true;
}
return false;
}
function checkIfTimeToSkip(currentVideoTime, startTime, endTime) {
//If the sponsor time is in between these times, skip it
//Checks if the last time skipped to is not too close to now, to make sure not to get too many
// sponsor times in a row (from one troll)
//the last term makes 0 second start times possible only if the video is not setup to start at a different time from zero
return (Math.abs(currentVideoTime - startTime) < 3 && startTime >= lastTime && startTime <= currentVideoTime) ||
(lastTime == -1 && startTime == 0 && currentVideoTime < endTime)
}
//skip fromt he start time to the end time for a certain index sponsor time
//skip from fhe start time to the end time for a certain index sponsor time
function skipToTime(v, index, sponsorTimes, openNotice) {
if (!Config.config.disableAutoSkip || previewResetter !== null) {
v.currentTime = sponsorTimes[index][1];