Reliability fixes

This commit is contained in:
goodtube4u
2024-07-06 13:29:46 +10:00
parent 4dc26d7440
commit 2cdeebbca0

View File

@@ -1,7 +1,7 @@
// ==UserScript== // ==UserScript==
// @name GoodTube // @name GoodTube
// @namespace http://tampermonkey.net/ // @namespace http://tampermonkey.net/
// @version 4.031 // @version 4.500
// @description Loads Youtube videos from different sources. Also removes ads, shorts, etc. // @description Loads Youtube videos from different sources. Also removes ads, shorts, etc.
// @author GoodTube // @author GoodTube
// @match https://*.youtube.com/* // @match https://*.youtube.com/*
@@ -409,7 +409,6 @@
let goodTube_player_loadAssetAttempts = 0; let goodTube_player_loadAssetAttempts = 0;
let goodTube_player_loadVideoDataAttempts = 0; let goodTube_player_loadVideoDataAttempts = 0;
let goodTube_player_loadChaptersAttempts = 0; let goodTube_player_loadChaptersAttempts = 0;
let goodTube_player_downloadFileAsBlobAttempts = [];
let goodTube_player_vttThumbnailsFunction = false; let goodTube_player_vttThumbnailsFunction = false;
let goodTube_player_reloadVideoAttempts = 1; let goodTube_player_reloadVideoAttempts = 1;
let goodTube_player_ended = false; let goodTube_player_ended = false;
@@ -1555,7 +1554,7 @@
// Select API // Select API
let goodTube_automaticServerIndex = 0; let goodTube_automaticServerIndex = 0;
function goodTube_player_selectApi(url) { function goodTube_player_selectApi(url, reloadVideoData) {
// Target the source menu // Target the source menu
let menu = document.querySelector('.vjs-source-button .vjs-menu'); let menu = document.querySelector('.vjs-source-button .vjs-menu');
@@ -1620,7 +1619,6 @@
goodTube_automaticServerIndex = 0; goodTube_automaticServerIndex = 0;
} }
// Select the currently selected item // Select the currently selected item
let menuItems = menu.querySelectorAll('ul li'); let menuItems = menu.querySelectorAll('ul li');
menuItems.forEach((menuItem) => { menuItems.forEach((menuItem) => {
@@ -1628,6 +1626,11 @@
menuItem.classList.add('vjs-selected'); menuItem.classList.add('vjs-selected');
} }
}); });
// Reload video data
if (reloadVideoData) {
goodTube_player_reloadVideoData();
}
} }
// Pause // Pause
@@ -1651,7 +1654,6 @@
} }
// Load video // Load video
let goodTube_fetchTimeout = false;
function goodTube_player_loadVideo(player) { function goodTube_player_loadVideo(player) {
// If we're not viewing a video // If we're not viewing a video
if (typeof goodTube_getParams['v'] === 'undefined') { if (typeof goodTube_getParams['v'] === 'undefined') {
@@ -1706,31 +1708,12 @@
apiEndpoint = goodTube_api_url+"/streams/"+goodTube_getParams['v']; apiEndpoint = goodTube_api_url+"/streams/"+goodTube_getParams['v'];
} }
// Clear any fetch timeouts // Call the API (die after 5s)
if (goodTube_fetchTimeout) { fetch(apiEndpoint, {
clearTimeout(goodTube_fetchTimeout); signal: AbortSignal.timeout(5000)
} })
// Make sure fetch completes in 5s
goodTube_fetchTimeout = setTimeout(function() {
goodTube_player_selectApi('automatic');
// Debug message
if (goodTube_debug) {
console.log('\n-------------------------\n\n');
console.log('[GoodTube] Loading video data from '+goodTube_api_name+'...');
}
}, 5000);
// Get the video data (and die after 5s)
fetch(apiEndpoint, { signal: AbortSignal.timeout(5000) })
.then(response => response.text()) .then(response => response.text())
.then(data => { .then(data => {
// Clear any fetch timeouts
if (goodTube_fetchTimeout) {
clearTimeout(goodTube_fetchTimeout);
}
// Add the loading state // Add the loading state
goodTube_player_addLoadingState(); goodTube_player_addLoadingState();
@@ -2031,11 +2014,6 @@
}) })
// If there's any issues loading the video data, try again (after configured delay time) // If there's any issues loading the video data, try again (after configured delay time)
.catch((error) => { .catch((error) => {
// Clear any fetch timeouts
if (goodTube_fetchTimeout) {
clearTimeout(goodTube_fetchTimeout);
}
if (typeof goodTube_pendingRetry['loadVideoData'] !== 'undefined') { if (typeof goodTube_pendingRetry['loadVideoData'] !== 'undefined') {
clearTimeout(goodTube_pendingRetry['loadVideoData']); clearTimeout(goodTube_pendingRetry['loadVideoData']);
} }
@@ -2419,8 +2397,10 @@
} }
goodTube_otherDataServersIndex_subtitles++; goodTube_otherDataServersIndex_subtitles++;
// Get the subtitle // Get the subtitle (die after 5s)
fetch(subtitleApi+subtitleData[0]['url']) fetch(subtitleApi+subtitleData[0]['url'], {
signal: AbortSignal.timeout(5000)
})
.then(response => response.text()) .then(response => response.text())
.then(data => { .then(data => {
// If the data wasn't right, try the next fallback server // If the data wasn't right, try the next fallback server
@@ -2488,8 +2468,10 @@
if (goodTube_api_type === 3) { if (goodTube_api_type === 3) {
let apiEndpoint = goodTube_otherDataServers[fallbackServerIndex]+"/api/v1/videos/"+goodTube_getParams['v']; let apiEndpoint = goodTube_otherDataServers[fallbackServerIndex]+"/api/v1/videos/"+goodTube_getParams['v'];
// Get the video data // Get the video data (die after 5s)
fetch(apiEndpoint) fetch(apiEndpoint, {
signal: AbortSignal.timeout(5000)
})
.then(response => response.text()) .then(response => response.text())
.then(data => { .then(data => {
// Turn video data into JSON // Turn video data into JSON
@@ -2547,7 +2529,10 @@
} }
// Otherwise we have data, so check the storyboard returned actually loads // Otherwise we have data, so check the storyboard returned actually loads
else { else {
fetch(storyboardApi+storyboardData[0]['url']) // Call the API (die after 5s)
fetch(storyboardApi+storyboardData[0]['url'], {
signal: AbortSignal.timeout(5000)
})
.then(response => response.text()) .then(response => response.text())
.then(data => { .then(data => {
// If it failed to get WEBVTT format, try the next fallback server // If it failed to get WEBVTT format, try the next fallback server
@@ -2573,7 +2558,10 @@
// If we found the URL of the first storyboard image, check it loads // If we found the URL of the first storyboard image, check it loads
if (gotTheUrl) { if (gotTheUrl) {
fetch(storyboardUrl) // Call the API (die after 5s)
fetch(storyboardUrl, {
signal: AbortSignal.timeout(5000)
})
.then(response => response.text()) .then(response => response.text())
.then(data => { .then(data => {
// Check the data returned, it should be an image not a HTML document (this often comes back when it fails to load) // Check the data returned, it should be an image not a HTML document (this often comes back when it fails to load)
@@ -2677,7 +2665,7 @@
goodTube_player_videojs_hideError(); goodTube_player_videojs_hideError();
player.classList.add('goodTube_hidden'); player.classList.add('goodTube_hidden');
player.currentTime = 0; player.currentTime = 0;
player.setAttribute('src', ''); // player.setAttribute('src', '');
player.pause(); player.pause();
// Clear any existing chapters // Clear any existing chapters
@@ -2868,6 +2856,7 @@
let goodTube_videojs_fastForward = false; let goodTube_videojs_fastForward = false;
let goodTube_qualityApi = false; let goodTube_qualityApi = false;
let goodTube_bufferingTimeout = false; let goodTube_bufferingTimeout = false;
let goodTube_loadingTimeout = false;
// Init video js // Init video js
function goodTube_player_videojs() { function goodTube_player_videojs() {
@@ -2975,16 +2964,13 @@
goodTube_automaticServerIndex = 0; goodTube_automaticServerIndex = 0;
} }
// Set the new API
goodTube_player_selectApi(menuItem.getAttribute('api'));
// Set the player time to be restored when the new server loads // Set the player time to be restored when the new server loads
if (goodTube_player.currentTime > 0) { if (goodTube_player.currentTime > 0) {
goodTube_player_restoreTime = goodTube_player.currentTime; goodTube_player_restoreTime = goodTube_player.currentTime;
} }
// Reload the video data // Set the new API
goodTube_player_reloadVideoData(); goodTube_player_selectApi(menuItem.getAttribute('api'), true);
} }
}); });
}); });
@@ -3508,7 +3494,7 @@
} }
// Init the API selection // Init the API selection
goodTube_player_selectApi(goodTube_helper_getCookie('goodTube_api_withauto')); goodTube_player_selectApi(goodTube_helper_getCookie('goodTube_api_withauto'), false);
// Update the video js player // Update the video js player
goodTube_player_videojs_update(); goodTube_player_videojs_update();
@@ -3532,13 +3518,11 @@
console.log('[GoodTube] Video not loading fast enough - selecting next video source...'); console.log('[GoodTube] Video not loading fast enough - selecting next video source...');
} }
goodTube_player_selectApi('automatic');
// Set the player time to be restored when the new server loads // Set the player time to be restored when the new server loads
goodTube_player_restoreTime = goodTube_player.currentTime; goodTube_player_restoreTime = goodTube_player.currentTime;
// Reload the video data // Get the next server
goodTube_player_reloadVideoData(); goodTube_player_selectApi('automatic', true);
} }
}, 10000); }, 10000);
} }
@@ -3557,6 +3541,11 @@
// Once the metadata has loaded // Once the metadata has loaded
goodTube_videojs_player.on('loadedmetadata', function() { goodTube_videojs_player.on('loadedmetadata', function() {
// Clear any loading timeouts
if (goodTube_loadingTimeout) {
clearTimeout(goodTube_loadingTimeout);
}
// Skip to remembered time once loaded metadata (if there's a get param of 't') // Skip to remembered time once loaded metadata (if there's a get param of 't')
if (typeof goodTube_getParams['t'] !== 'undefined') { if (typeof goodTube_getParams['t'] !== 'undefined') {
let time = goodTube_getParams['t'].replace('s', ''); let time = goodTube_getParams['t'].replace('s', '');
@@ -3579,10 +3568,25 @@
// Debug message to show the video is loading // Debug message to show the video is loading
goodTube_videojs_player.on('loadstart', function() { goodTube_videojs_player.on('loadstart', function() {
// Clear any loading timeouts
if (goodTube_loadingTimeout) {
clearTimeout(goodTube_loadingTimeout);
}
// If we've been waiting more than 10s, select the next server
goodTube_loadingTimeout = setTimeout(function() {
// Debug message
if (goodTube_debug) {
console.log('[GoodTube] Video not loading fast enough - selecting next video source...');
}
// Get the next server
goodTube_player_selectApi('automatic', true);
}, 10000);
// Enable the player // Enable the player
goodTube_player.classList.remove('goodTube_hidden'); goodTube_player.classList.remove('goodTube_hidden');
// Server 1 quality stuff // Server 1 quality stuff
if (goodTube_api_type === 1) { if (goodTube_api_type === 1) {
let qualityLabel = ''; let qualityLabel = '';
@@ -4696,6 +4700,14 @@
// Show an error on screen, or select next server if we're on automatic mode // Show an error on screen, or select next server if we're on automatic mode
function goodTube_player_videojs_handleError() { function goodTube_player_videojs_handleError() {
// Clear any buffering and loading timeouts
if (goodTube_bufferingTimeout) {
clearTimeout(goodTube_bufferingTimeout);
}
if (goodTube_loadingTimeout) {
clearTimeout(goodTube_loadingTimeout);
}
// What api are we on? // What api are we on?
let selectedApi = goodTube_helper_getCookie('goodTube_api_withauto'); let selectedApi = goodTube_helper_getCookie('goodTube_api_withauto');
@@ -4712,6 +4724,9 @@
// Remove the loading state // Remove the loading state
goodTube_player_removeLoadingState(); goodTube_player_removeLoadingState();
// Clear the player
goodTube_player_clear(goodTube_player);
let error = document.createElement('div'); let error = document.createElement('div');
error.setAttribute('id', 'goodTube_error'); error.setAttribute('id', 'goodTube_error');
error.innerHTML = "Video could not be loaded. The servers are not responding :(<br><small>Please refresh the page / try again soon!</small>"; error.innerHTML = "Video could not be loaded. The servers are not responding :(<br><small>Please refresh the page / try again soon!</small>";
@@ -4726,16 +4741,13 @@
console.log('[GoodTube] Video could not be loaded - selecting next video source...'); console.log('[GoodTube] Video could not be loaded - selecting next video source...');
} }
// Select next server
goodTube_player_selectApi('automatic');
// Set the player time to be restored when the new server loads // Set the player time to be restored when the new server loads
if (goodTube_player.currentTime > 0) { if (goodTube_player.currentTime > 0) {
goodTube_player_restoreTime = goodTube_player.currentTime; goodTube_player_restoreTime = goodTube_player.currentTime;
} }
// Reload the video data // Select next server
goodTube_player_reloadVideoData(); goodTube_player_selectApi('automatic', true);
} }
@@ -4746,17 +4758,14 @@
console.log('[GoodTube] Video could not be loaded - selecting next video source...'); console.log('[GoodTube] Video could not be loaded - selecting next video source...');
} }
// Go to automatic mode
goodTube_automaticServerIndex = 0;
goodTube_player_selectApi('automatic');
// Set the player time to be restored when the new server loads // Set the player time to be restored when the new server loads
if (goodTube_player.currentTime > 0) { if (goodTube_player.currentTime > 0) {
goodTube_player_restoreTime = goodTube_player.currentTime; goodTube_player_restoreTime = goodTube_player.currentTime;
} }
// Reload the video data // Go to automatic mode
goodTube_player_reloadVideoData(); goodTube_automaticServerIndex = 0;
goodTube_player_selectApi('automatic', true);
} }
} }
@@ -4936,13 +4945,6 @@
'proxy': true, 'proxy': true,
'url': 'https://pipedapi.r4fo.com' 'url': 'https://pipedapi.r4fo.com'
}, },
// // FAST
// {
// 'name': 'Phoenix (US)',
// 'type': 3,
// 'proxy': true,
// 'url': 'https://pipedapi.drgns.space'
// },
// FAST // FAST
{ {
'name': 'Ra (US)', 'name': 'Ra (US)',
@@ -4965,6 +4967,13 @@
'url': 'https://pipedapi.darkness.services' 'url': 'https://pipedapi.darkness.services'
}, },
// FAST // FAST
{
'name': 'Phoenix (US)',
'type': 3,
'proxy': true,
'url': 'https://pipedapi.drgns.space'
},
// FAST
{ {
'name': 'Acid (US)', 'name': 'Acid (US)',
'type': 2, 'type': 2,
@@ -5062,6 +5071,7 @@
'proxy': true, 'proxy': true,
'url': 'https://schaunapi.ehwurscht.at' 'url': 'https://schaunapi.ehwurscht.at'
}, },
// // SLOW // // SLOW
// { // {
// 'name': 'Centaur (FR)', // 'name': 'Centaur (FR)',
@@ -5509,6 +5519,9 @@
return; return;
} }
// Show the downloading indicator
goodTube_player_videojs_showDownloading();
// Delay calling the API 3s since it was last called // Delay calling the API 3s since it was last called
let delaySeconds = 0; let delaySeconds = 0;
let currentTimeSeconds = new Date().getTime() / 1000; let currentTimeSeconds = new Date().getTime() / 1000;
@@ -5523,8 +5536,12 @@
goodTube_helper_setCookie('goodTube_lastDownloadTimeSeconds', (currentTimeSeconds + delaySeconds)); goodTube_helper_setCookie('goodTube_lastDownloadTimeSeconds', (currentTimeSeconds + delaySeconds));
goodTube_downloadTimeouts[youtubeId] = setTimeout(function() { goodTube_downloadTimeouts[youtubeId] = setTimeout(function() {
// Show the downloading indicator // Debug message
goodTube_player_videojs_showDownloading(); if (goodTube_debug) {
if (typeof fileName !== 'undefined') {
console.log('[GoodTube] Downloading '+type+' - '+fileName+'...');
}
}
// CODEC: // CODEC:
// Desktop tries in this order: vp9, av1, h264 // Desktop tries in this order: vp9, av1, h264
@@ -5556,8 +5573,9 @@
'isAudioOnly': isAudioOnly 'isAudioOnly': isAudioOnly
}); });
// Call the API // Call the API (die after 10s)
fetch(goodTube_downloadServers[serverIndex]+'/api/json', { fetch(goodTube_downloadServers[serverIndex]+'/api/json', {
signal: AbortSignal.timeout(10000),
method: 'POST', method: 'POST',
headers: { headers: {
'Accept': 'application/json', 'Accept': 'application/json',
@@ -5567,6 +5585,7 @@
}) })
.then(response => response.text()) .then(response => response.text())
.then(data => { .then(data => {
// console.log('success', data);
// Stop if this is no longer a pending download // Stop if this is no longer a pending download
if (typeof goodTube_pendingDownloads[youtubeId] === 'undefined') { if (typeof goodTube_pendingDownloads[youtubeId] === 'undefined') {
return; return;
@@ -5590,23 +5609,6 @@
// If there was an error returned from the API // If there was an error returned from the API
if (typeof data['status'] !== 'undefined' && data['status'] === 'error') { if (typeof data['status'] !== 'undefined' && data['status'] === 'error') {
// Try again if the API is down.
// There should be an error with the word 'api' in it if this happens.
if (typeof data['text'] !== 'undefined' && data['text'].toLowerCase().indexOf('api') !== -1) {
if (typeof goodTube_pendingRetry['download_'+youtubeId] !== 'undefined') {
clearTimeout(goodTube_pendingRetry['download_'+youtubeId]);
}
serverIndex++;
goodTube_pendingRetry['download_'+youtubeId] = setTimeout(function() {
goodTube_download(serverIndex, type, youtubeId, fileName);
}, goodTube_retryDelay);
return;
}
// If there was an issue with the codec, try the next one. // If there was an issue with the codec, try the next one.
// There should be an error with the word 'settings' in it if this happens. // There should be an error with the word 'settings' in it if this happens.
let nextCodec = false; let nextCodec = false;
@@ -5624,7 +5626,7 @@
} }
// Mobile // Mobile
if (window.location.href.indexOf('m.youtube') === -1) { if (window.location.href.indexOf('m.youtube') !== -1) {
if (vCodec === 'h264') { if (vCodec === 'h264') {
nextCodec = 'av1'; nextCodec = 'av1';
} }
@@ -5666,6 +5668,20 @@
return; return;
} }
} }
// All other errors, just try again
else {
if (typeof goodTube_pendingRetry['download_'+youtubeId] !== 'undefined') {
clearTimeout(goodTube_pendingRetry['download_'+youtubeId]);
}
serverIndex++;
goodTube_pendingRetry['download_'+youtubeId] = setTimeout(function() {
goodTube_download(serverIndex, type, youtubeId, fileName);
}, goodTube_retryDelay);
return;
}
} }
// If the data is all good // If the data is all good
@@ -5691,12 +5707,14 @@
} }
// Download the file with a file name (as a blob, this is used for playlists - DESKTOP ONLY) // Download the file with a file name (as a blob, this is used for playlists - DESKTOP ONLY)
else { else {
goodTube_downloadFileAsBlob(data['url'], type, fileName, youtubeId); goodTube_downloadFileAsBlob(data['url'], type, fileName, youtubeId, serverIndex);
} }
} }
}) })
// If anything went wrong, try again // If anything went wrong, try again
.catch((error) => { .catch((error) => {
// console.log('error', error);
if (typeof goodTube_pendingRetry['download_'+youtubeId] !== 'undefined') { if (typeof goodTube_pendingRetry['download_'+youtubeId] !== 'undefined') {
clearTimeout(goodTube_pendingRetry['download_'+youtubeId]); clearTimeout(goodTube_pendingRetry['download_'+youtubeId]);
} }
@@ -5747,7 +5765,7 @@
// Make sure the data is all good // Make sure the data is all good
if (playlistItems.length <= 0) { if (playlistItems.length <= 0) {
if (goodTube_debug) { if (goodTube_debug) {
console.log('[GoodTube] Downloading failed, could not find playlist data'); console.log('[GoodTube] Downloading failed, could not find playlist data.');
} }
return; return;
@@ -5772,7 +5790,7 @@
// Make sure the data is all good // Make sure the data is all good
if (!fileName || !url) { if (!fileName || !url) {
if (goodTube_debug) { if (goodTube_debug) {
console.log('[GoodTube] Downloading failed, could not find playlist data'); console.log('[GoodTube] Downloading failed, could not find playlist data.');
} }
return; return;
@@ -5802,45 +5820,25 @@
} }
// Download a file as blob (this allows us to name it - so we use it for playlists - but it's doesn't actually download the file until fully loaded in the browser, which is kinda bad UX - but for now, it works!) // Download a file as blob (this allows us to name it - so we use it for playlists - but it's doesn't actually download the file until fully loaded in the browser, which is kinda bad UX - but for now, it works!)
function goodTube_downloadFileAsBlob(url, type, fileName, youtubeId) { function goodTube_downloadFileAsBlob(url, type, fileName, youtubeId, serverIndex) {
// Stop if this is no longer a pending download // Stop if this is no longer a pending download
if (typeof goodTube_pendingDownloads[youtubeId] === 'undefined') { if (typeof goodTube_pendingDownloads[youtubeId] === 'undefined') {
return; return;
} }
// Only re-attempt to download the max configured retry attempts
if (typeof goodTube_player_downloadFileAsBlobAttempts[url] === 'undefined') {
goodTube_player_downloadFileAsBlobAttempts[url] = 0;
}
goodTube_player_downloadFileAsBlobAttempts[url]++;
if (goodTube_player_downloadFileAsBlobAttempts[url] > goodTube_retryAttempts) {
// Debug message
if (goodTube_debug) {
console.log('[GoodTube] '+type.charAt(0).toUpperCase()+type.slice(1)+' - '+fileName+' could not be downloaded. Please try again soon.');
}
// Hide the downloading indicator
goodTube_player_videojs_hideDownloading();
return;
}
// Show the downloading indicator // Show the downloading indicator
goodTube_player_videojs_showDownloading(); goodTube_player_videojs_showDownloading();
// Debug message
if (goodTube_debug) {
console.log('[GoodTube] Downloading '+type+' - '+fileName+'...');
}
// Set the file extension based on the type // Set the file extension based on the type
let fileExtension = '.mp4'; let fileExtension = '.mp4';
if (type === 'audio') { if (type === 'audio') {
fileExtension = '.mp3'; fileExtension = '.mp3';
} }
fetch(url) // Call the API (die after 10s)
fetch(url, {
signal: AbortSignal.timeout(10000)
})
.then(response => response.blob()) .then(response => response.blob())
.then(blob => { .then(blob => {
// Stop if this is no longer a pending download // Stop if this is no longer a pending download
@@ -5849,12 +5847,12 @@
} }
// Get the blob // Get the blob
let url = URL.createObjectURL(blob); let blobUrl = URL.createObjectURL(blob);
// Create a download link element and set params // Create a download link element and set params
let a = document.createElement('a'); let a = document.createElement('a');
a.style.display = 'none'; a.style.display = 'none';
a.href = url; a.href = blobUrl;
a.download = fileName+fileExtension; a.download = fileName+fileExtension;
document.body.appendChild(a); document.body.appendChild(a);
@@ -5862,7 +5860,7 @@
a.click(); a.click();
// Remove the blob from memory // Remove the blob from memory
window.URL.revokeObjectURL(url); window.URL.revokeObjectURL(blobUrl);
// Remove the link // Remove the link
a.remove(); a.remove();
@@ -5880,14 +5878,16 @@
// Hide the downloading indicator // Hide the downloading indicator
goodTube_player_videojs_hideDownloading(); goodTube_player_videojs_hideDownloading();
}) })
// If anything went wrong, try again // If anything went wrong, try again (next download server)
.catch((error) => { .catch((error) => {
if (typeof goodTube_pendingRetry['downloadFileAsBlob_'+url] !== 'undefined') { if (typeof goodTube_pendingRetry['download_'+youtubeId] !== 'undefined') {
clearTimeout(goodTube_pendingRetry['downloadFileAsBlob_'+url]); clearTimeout(goodTube_pendingRetry['download_'+youtubeId]);
} }
goodTube_pendingRetry['downloadFileAsBlob_'+url] = setTimeout(function() { serverIndex++;
goodTube_downloadFileAsBlob(url, type, fileName, youtubeId);
goodTube_pendingRetry['download_'+youtubeId] = setTimeout(function() {
goodTube_download(serverIndex, type, youtubeId, fileName);
}, goodTube_retryDelay); }, goodTube_retryDelay);
}); });
} }
@@ -6086,7 +6086,7 @@
goodTube_player_restoreTime = 0; goodTube_player_restoreTime = 0;
if (goodTube_helper_getCookie('goodTube_api_withauto') === 'automatic') { if (goodTube_helper_getCookie('goodTube_api_withauto') === 'automatic') {
goodTube_player_selectApi('automatic'); goodTube_player_selectApi('automatic', false);
} }
// Debug message // Debug message
@@ -6183,6 +6183,11 @@
}); });
} }
// Ensure that if they close the window in the middle of downloads, we reset the last download time
window.addEventListener("beforeunload", (event) => {
goodTube_helper_setCookie('goodTube_lastDownloadTimeSeconds', (new Date().getTime() / 1000));
});
// Mute, pause and skip ads on all Youtube as much as possible // Mute, pause and skip ads on all Youtube as much as possible
setInterval(goodTube_youtube_mutePauseSkipAds, 1); setInterval(goodTube_youtube_mutePauseSkipAds, 1);
@@ -6228,5 +6233,4 @@
------------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------------ */
goodTube_init(); goodTube_init();
})(); })();