mirror of
https://github.com/pixeltris/TwitchAdSolutions.git
synced 2025-04-29 14:14:36 +02:00
Add Worker check from AdGuard Extra #276
This commit is contained in:
parent
39666c7bb1
commit
144bc99a61
@ -1,48 +1,6 @@
|
|||||||
twitch-videoad.js text/javascript
|
twitch-videoad.js text/javascript
|
||||||
(function() {
|
(function() {
|
||||||
if ( /(^|\.)twitch\.tv$/.test(document.location.hostname) === false ) { return; }
|
if ( /(^|\.)twitch\.tv$/.test(document.location.hostname) === false ) { return; }
|
||||||
//This stops Twitch from pausing the player when in another tab and an ad shows.
|
|
||||||
try {
|
|
||||||
Object.defineProperty(document, 'visibilityState', {
|
|
||||||
get() {
|
|
||||||
return 'visible';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Object.defineProperty(document, 'hidden', {
|
|
||||||
get() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const block = e => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
e.stopImmediatePropagation();
|
|
||||||
};
|
|
||||||
const process = e => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
e.stopImmediatePropagation();
|
|
||||||
//This corrects the background tab buffer bug when switching to the background tab for the first time after an extended period.
|
|
||||||
doTwitchPlayerTask(false, false, true, false, false);
|
|
||||||
};
|
|
||||||
document.addEventListener('visibilitychange', block, true);
|
|
||||||
document.addEventListener('webkitvisibilitychange', block, true);
|
|
||||||
document.addEventListener('mozvisibilitychange', block, true);
|
|
||||||
document.addEventListener('hasFocus', block, true);
|
|
||||||
if (/Firefox/.test(navigator.userAgent)) {
|
|
||||||
Object.defineProperty(document, 'mozHidden', {
|
|
||||||
get() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
Object.defineProperty(document, 'webkitHidden', {
|
|
||||||
get() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (err) {}
|
|
||||||
function declareOptions(scope) {
|
function declareOptions(scope) {
|
||||||
scope.AdSignifier = 'stitched';
|
scope.AdSignifier = 'stitched';
|
||||||
scope.ClientID = 'kimne78kx3ncx6brgo4mv6wki5h1ko';
|
scope.ClientID = 'kimne78kx3ncx6brgo4mv6wki5h1ko';
|
||||||
@ -63,186 +21,187 @@ twitch-videoad.js text/javascript
|
|||||||
scope.ClientIntegrityHeader = null;
|
scope.ClientIntegrityHeader = null;
|
||||||
scope.AuthorizationHeader = null;
|
scope.AuthorizationHeader = null;
|
||||||
}
|
}
|
||||||
declareOptions(window);
|
|
||||||
var twitchWorkers = [];
|
var twitchWorkers = [];
|
||||||
var adBlockDiv = null;
|
var adBlockDiv = null;
|
||||||
var OriginalVideoPlayerQuality = null;
|
var OriginalVideoPlayerQuality = null;
|
||||||
var IsPlayerAutoQuality = null;
|
var IsPlayerAutoQuality = null;
|
||||||
const oldWorker = window.Worker;
|
const oldWorker = window.Worker;
|
||||||
window.Worker = class Worker extends oldWorker {
|
function hookWindowWorker() {
|
||||||
constructor(twitchBlobUrl, options) {
|
window.Worker = class Worker extends oldWorker {
|
||||||
var isTwitchWorker = false;
|
constructor(twitchBlobUrl, options) {
|
||||||
try {
|
var isTwitchWorker = false;
|
||||||
isTwitchWorker = new URL(twitchBlobUrl).origin.endsWith('.twitch.tv');
|
try {
|
||||||
} catch {}
|
isTwitchWorker = new URL(twitchBlobUrl).origin.endsWith('.twitch.tv');
|
||||||
if (!isTwitchWorker) {
|
} catch {}
|
||||||
super(twitchBlobUrl, options);
|
if (!isTwitchWorker) {
|
||||||
return;
|
super(twitchBlobUrl, options);
|
||||||
}
|
return;
|
||||||
var newBlobStr = `
|
|
||||||
${getStreamUrlForResolution.toString()}
|
|
||||||
${getStreamForResolution.toString()}
|
|
||||||
${stripUnusedParams.toString()}
|
|
||||||
${processM3U8.toString()}
|
|
||||||
${hookWorkerFetch.toString()}
|
|
||||||
${declareOptions.toString()}
|
|
||||||
${getAccessToken.toString()}
|
|
||||||
${gqlRequest.toString()}
|
|
||||||
${adRecordgqlPacket.toString()}
|
|
||||||
${tryNotifyTwitch.toString()}
|
|
||||||
${parseAttributes.toString()}
|
|
||||||
${getWasmWorkerUrl.toString()}
|
|
||||||
var workerUrl = getWasmWorkerUrl('${twitchBlobUrl.replaceAll("'", "%27")}');
|
|
||||||
if (workerUrl && workerUrl.includes('assets.twitch.tv/assets/amazon-ivs-wasmworker')) {
|
|
||||||
declareOptions(self);
|
|
||||||
self.addEventListener('message', function(e) {
|
|
||||||
if (e.data.key == 'UpdateIsSquadStream') {
|
|
||||||
IsSquadStream = e.data.value;
|
|
||||||
} else if (e.data.key == 'UpdateClientVersion') {
|
|
||||||
ClientVersion = e.data.value;
|
|
||||||
} else if (e.data.key == 'UpdateClientSession') {
|
|
||||||
ClientSession = e.data.value;
|
|
||||||
} else if (e.data.key == 'UpdateClientId') {
|
|
||||||
ClientID = e.data.value;
|
|
||||||
} else if (e.data.key == 'UpdateDeviceId') {
|
|
||||||
GQLDeviceID = e.data.value;
|
|
||||||
} else if (e.data.key == 'UpdateClientIntegrityHeader') {
|
|
||||||
ClientIntegrityHeader = e.data.value;
|
|
||||||
} else if (e.data.key == 'UpdateAuthorizationHeader') {
|
|
||||||
AuthorizationHeader = e.data.value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
hookWorkerFetch();
|
|
||||||
importScripts(workerUrl);
|
|
||||||
}
|
}
|
||||||
`;
|
var newBlobStr = `
|
||||||
super(URL.createObjectURL(new Blob([newBlobStr])), options);
|
${getStreamUrlForResolution.toString()}
|
||||||
twitchWorkers.push(this);
|
${getStreamForResolution.toString()}
|
||||||
this.onmessage = function(e) {
|
${stripUnusedParams.toString()}
|
||||||
if (e.data.key == 'ShowAdBlockBanner') {
|
${processM3U8.toString()}
|
||||||
if (adBlockDiv == null) {
|
${hookWorkerFetch.toString()}
|
||||||
adBlockDiv = getAdBlockDiv();
|
${declareOptions.toString()}
|
||||||
|
${getAccessToken.toString()}
|
||||||
|
${gqlRequest.toString()}
|
||||||
|
${adRecordgqlPacket.toString()}
|
||||||
|
${tryNotifyTwitch.toString()}
|
||||||
|
${parseAttributes.toString()}
|
||||||
|
${getWasmWorkerUrl.toString()}
|
||||||
|
var workerUrl = getWasmWorkerUrl('${twitchBlobUrl.replaceAll("'", "%27")}');
|
||||||
|
if (workerUrl && workerUrl.includes('assets.twitch.tv/assets/amazon-ivs-wasmworker')) {
|
||||||
|
declareOptions(self);
|
||||||
|
self.addEventListener('message', function(e) {
|
||||||
|
if (e.data.key == 'UpdateIsSquadStream') {
|
||||||
|
IsSquadStream = e.data.value;
|
||||||
|
} else if (e.data.key == 'UpdateClientVersion') {
|
||||||
|
ClientVersion = e.data.value;
|
||||||
|
} else if (e.data.key == 'UpdateClientSession') {
|
||||||
|
ClientSession = e.data.value;
|
||||||
|
} else if (e.data.key == 'UpdateClientId') {
|
||||||
|
ClientID = e.data.value;
|
||||||
|
} else if (e.data.key == 'UpdateDeviceId') {
|
||||||
|
GQLDeviceID = e.data.value;
|
||||||
|
} else if (e.data.key == 'UpdateClientIntegrityHeader') {
|
||||||
|
ClientIntegrityHeader = e.data.value;
|
||||||
|
} else if (e.data.key == 'UpdateAuthorizationHeader') {
|
||||||
|
AuthorizationHeader = e.data.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
hookWorkerFetch();
|
||||||
|
importScripts(workerUrl);
|
||||||
}
|
}
|
||||||
adBlockDiv.P.textContent = 'Blocking ads';
|
`;
|
||||||
adBlockDiv.style.display = 'block';
|
super(URL.createObjectURL(new Blob([newBlobStr])), options);
|
||||||
} else if (e.data.key == 'HideAdBlockBanner') {
|
twitchWorkers.push(this);
|
||||||
if (adBlockDiv == null) {
|
this.onmessage = function(e) {
|
||||||
adBlockDiv = getAdBlockDiv();
|
if (e.data.key == 'ShowAdBlockBanner') {
|
||||||
}
|
if (adBlockDiv == null) {
|
||||||
adBlockDiv.style.display = 'none';
|
adBlockDiv = getAdBlockDiv();
|
||||||
} else if (e.data.key == 'PauseResumePlayer') {
|
|
||||||
doTwitchPlayerTask(true, false, false, false, false);
|
|
||||||
} else if (e.data.key == 'ForceChangeQuality') {
|
|
||||||
//This is used to fix the bug where the video would freeze.
|
|
||||||
try {
|
|
||||||
//if (navigator.userAgent.toLowerCase().indexOf('firefox') == -1) {
|
|
||||||
return;
|
|
||||||
//}
|
|
||||||
var autoQuality = doTwitchPlayerTask(false, false, false, true, false);
|
|
||||||
var currentQuality = doTwitchPlayerTask(false, true, false, false, false);
|
|
||||||
if (IsPlayerAutoQuality == null) {
|
|
||||||
IsPlayerAutoQuality = autoQuality;
|
|
||||||
}
|
}
|
||||||
if (OriginalVideoPlayerQuality == null) {
|
adBlockDiv.P.textContent = 'Blocking ads';
|
||||||
OriginalVideoPlayerQuality = currentQuality;
|
adBlockDiv.style.display = 'block';
|
||||||
|
} else if (e.data.key == 'HideAdBlockBanner') {
|
||||||
|
if (adBlockDiv == null) {
|
||||||
|
adBlockDiv = getAdBlockDiv();
|
||||||
}
|
}
|
||||||
if (!currentQuality.includes('360') || e.data.value != null) {
|
adBlockDiv.style.display = 'none';
|
||||||
if (!OriginalVideoPlayerQuality.includes('360')) {
|
} else if (e.data.key == 'PauseResumePlayer') {
|
||||||
var settingsMenu = document.querySelector('div[data-a-target="player-settings-menu"]');
|
doTwitchPlayerTask(true, false, false, false, false);
|
||||||
if (settingsMenu == null) {
|
} else if (e.data.key == 'ForceChangeQuality') {
|
||||||
var settingsCog = document.querySelector('button[data-a-target="player-settings-button"]');
|
//This is used to fix the bug where the video would freeze.
|
||||||
if (settingsCog) {
|
try {
|
||||||
settingsCog.click();
|
//if (navigator.userAgent.toLowerCase().indexOf('firefox') == -1) {
|
||||||
var qualityMenu = document.querySelector('button[data-a-target="player-settings-menu-item-quality"]');
|
return;
|
||||||
if (qualityMenu) {
|
//}
|
||||||
qualityMenu.click();
|
var autoQuality = doTwitchPlayerTask(false, false, false, true, false);
|
||||||
}
|
var currentQuality = doTwitchPlayerTask(false, true, false, false, false);
|
||||||
var lowQuality = document.querySelectorAll('input[data-a-target="tw-radio"');
|
if (IsPlayerAutoQuality == null) {
|
||||||
if (lowQuality) {
|
IsPlayerAutoQuality = autoQuality;
|
||||||
var qualityToSelect = lowQuality.length - 2;
|
}
|
||||||
if (e.data.value != null) {
|
if (OriginalVideoPlayerQuality == null) {
|
||||||
if (e.data.value.includes('original')) {
|
OriginalVideoPlayerQuality = currentQuality;
|
||||||
e.data.value = OriginalVideoPlayerQuality;
|
}
|
||||||
if (IsPlayerAutoQuality) {
|
if (!currentQuality.includes('360') || e.data.value != null) {
|
||||||
e.data.value = 'auto';
|
if (!OriginalVideoPlayerQuality.includes('360')) {
|
||||||
|
var settingsMenu = document.querySelector('div[data-a-target="player-settings-menu"]');
|
||||||
|
if (settingsMenu == null) {
|
||||||
|
var settingsCog = document.querySelector('button[data-a-target="player-settings-button"]');
|
||||||
|
if (settingsCog) {
|
||||||
|
settingsCog.click();
|
||||||
|
var qualityMenu = document.querySelector('button[data-a-target="player-settings-menu-item-quality"]');
|
||||||
|
if (qualityMenu) {
|
||||||
|
qualityMenu.click();
|
||||||
|
}
|
||||||
|
var lowQuality = document.querySelectorAll('input[data-a-target="tw-radio"');
|
||||||
|
if (lowQuality) {
|
||||||
|
var qualityToSelect = lowQuality.length - 2;
|
||||||
|
if (e.data.value != null) {
|
||||||
|
if (e.data.value.includes('original')) {
|
||||||
|
e.data.value = OriginalVideoPlayerQuality;
|
||||||
|
if (IsPlayerAutoQuality) {
|
||||||
|
e.data.value = 'auto';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (e.data.value.includes('160p')) {
|
||||||
|
qualityToSelect = 5;
|
||||||
|
}
|
||||||
|
if (e.data.value.includes('360p')) {
|
||||||
|
qualityToSelect = 4;
|
||||||
|
}
|
||||||
|
if (e.data.value.includes('480p')) {
|
||||||
|
qualityToSelect = 3;
|
||||||
|
}
|
||||||
|
if (e.data.value.includes('720p')) {
|
||||||
|
qualityToSelect = 2;
|
||||||
|
}
|
||||||
|
if (e.data.value.includes('822p')) {
|
||||||
|
qualityToSelect = 2;
|
||||||
|
}
|
||||||
|
if (e.data.value.includes('864p')) {
|
||||||
|
qualityToSelect = 2;
|
||||||
|
}
|
||||||
|
if (e.data.value.includes('900p')) {
|
||||||
|
qualityToSelect = 2;
|
||||||
|
}
|
||||||
|
if (e.data.value.includes('936p')) {
|
||||||
|
qualityToSelect = 2;
|
||||||
|
}
|
||||||
|
if (e.data.value.includes('960p')) {
|
||||||
|
qualityToSelect = 2;
|
||||||
|
}
|
||||||
|
if (e.data.value.includes('1080p')) {
|
||||||
|
qualityToSelect = 2;
|
||||||
|
}
|
||||||
|
if (e.data.value.includes('source')) {
|
||||||
|
qualityToSelect = 1;
|
||||||
|
}
|
||||||
|
if (e.data.value.includes('auto')) {
|
||||||
|
qualityToSelect = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (e.data.value.includes('160p')) {
|
var currentQualityLS = window.localStorage.getItem('video-quality');
|
||||||
qualityToSelect = 5;
|
lowQuality[qualityToSelect].click();
|
||||||
|
settingsCog.click();
|
||||||
|
window.localStorage.setItem('video-quality', currentQualityLS);
|
||||||
|
if (e.data.value != null) {
|
||||||
|
OriginalVideoPlayerQuality = null;
|
||||||
|
IsPlayerAutoQuality = null;
|
||||||
|
doTwitchPlayerTask(false, false, false, true, true);
|
||||||
}
|
}
|
||||||
if (e.data.value.includes('360p')) {
|
|
||||||
qualityToSelect = 4;
|
|
||||||
}
|
|
||||||
if (e.data.value.includes('480p')) {
|
|
||||||
qualityToSelect = 3;
|
|
||||||
}
|
|
||||||
if (e.data.value.includes('720p')) {
|
|
||||||
qualityToSelect = 2;
|
|
||||||
}
|
|
||||||
if (e.data.value.includes('822p')) {
|
|
||||||
qualityToSelect = 2;
|
|
||||||
}
|
|
||||||
if (e.data.value.includes('864p')) {
|
|
||||||
qualityToSelect = 2;
|
|
||||||
}
|
|
||||||
if (e.data.value.includes('900p')) {
|
|
||||||
qualityToSelect = 2;
|
|
||||||
}
|
|
||||||
if (e.data.value.includes('936p')) {
|
|
||||||
qualityToSelect = 2;
|
|
||||||
}
|
|
||||||
if (e.data.value.includes('960p')) {
|
|
||||||
qualityToSelect = 2;
|
|
||||||
}
|
|
||||||
if (e.data.value.includes('1080p')) {
|
|
||||||
qualityToSelect = 2;
|
|
||||||
}
|
|
||||||
if (e.data.value.includes('source')) {
|
|
||||||
qualityToSelect = 1;
|
|
||||||
}
|
|
||||||
if (e.data.value.includes('auto')) {
|
|
||||||
qualityToSelect = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var currentQualityLS = window.localStorage.getItem('video-quality');
|
|
||||||
lowQuality[qualityToSelect].click();
|
|
||||||
settingsCog.click();
|
|
||||||
window.localStorage.setItem('video-quality', currentQualityLS);
|
|
||||||
if (e.data.value != null) {
|
|
||||||
OriginalVideoPlayerQuality = null;
|
|
||||||
IsPlayerAutoQuality = null;
|
|
||||||
doTwitchPlayerTask(false, false, false, true, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (err) {
|
||||||
|
OriginalVideoPlayerQuality = null;
|
||||||
|
IsPlayerAutoQuality = null;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
|
||||||
OriginalVideoPlayerQuality = null;
|
|
||||||
IsPlayerAutoQuality = null;
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
function getAdBlockDiv() {
|
||||||
function getAdBlockDiv() {
|
//To display a notification to the user, that an ad is being blocked.
|
||||||
//To display a notification to the user, that an ad is being blocked.
|
var playerRootDiv = document.querySelector('.video-player');
|
||||||
var playerRootDiv = document.querySelector('.video-player');
|
var adBlockDiv = null;
|
||||||
var adBlockDiv = null;
|
if (playerRootDiv != null) {
|
||||||
if (playerRootDiv != null) {
|
adBlockDiv = playerRootDiv.querySelector('.adblock-overlay');
|
||||||
adBlockDiv = playerRootDiv.querySelector('.adblock-overlay');
|
if (adBlockDiv == null) {
|
||||||
if (adBlockDiv == null) {
|
adBlockDiv = document.createElement('div');
|
||||||
adBlockDiv = document.createElement('div');
|
adBlockDiv.className = 'adblock-overlay';
|
||||||
adBlockDiv.className = 'adblock-overlay';
|
adBlockDiv.innerHTML = '<div class="player-adblock-notice" style="color: white; background-color: rgba(0, 0, 0, 0.8); position: absolute; top: 0px; left: 0px; padding: 5px;"><p></p></div>';
|
||||||
adBlockDiv.innerHTML = '<div class="player-adblock-notice" style="color: white; background-color: rgba(0, 0, 0, 0.8); position: absolute; top: 0px; left: 0px; padding: 5px;"><p></p></div>';
|
adBlockDiv.style.display = 'none';
|
||||||
adBlockDiv.style.display = 'none';
|
adBlockDiv.P = adBlockDiv.querySelector('p');
|
||||||
adBlockDiv.P = adBlockDiv.querySelector('p');
|
playerRootDiv.appendChild(adBlockDiv);
|
||||||
playerRootDiv.appendChild(adBlockDiv);
|
}
|
||||||
}
|
}
|
||||||
|
return adBlockDiv;
|
||||||
}
|
}
|
||||||
return adBlockDiv;
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
}
|
||||||
function getWasmWorkerUrl(twitchBlobUrl) {
|
function getWasmWorkerUrl(twitchBlobUrl) {
|
||||||
var req = new XMLHttpRequest();
|
var req = new XMLHttpRequest();
|
||||||
req.open('GET', twitchBlobUrl, false);
|
req.open('GET', twitchBlobUrl, false);
|
||||||
@ -853,5 +812,73 @@ twitch-videoad.js text/javascript
|
|||||||
return realFetch.apply(this, arguments);
|
return realFetch.apply(this, arguments);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
hookFetch();
|
function isWorkerIntact() {
|
||||||
|
// Taken from Adguard Extra
|
||||||
|
const iframe = window.document.createElement('iframe');
|
||||||
|
window.document.body.append(iframe);
|
||||||
|
const cleanWindow = iframe.contentWindow;
|
||||||
|
if (cleanWindow.Worker.toString() === window.Worker.toString()) {
|
||||||
|
iframe.remove();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
iframe.remove();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
function onContentLoaded() {
|
||||||
|
if (!isWorkerIntact()) {
|
||||||
|
console.log('Twitch Worker is already hooked');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.reloadTwitchPlayer = reloadTwitchPlayer;
|
||||||
|
declareOptions(window);
|
||||||
|
hookWindowWorker();
|
||||||
|
hookFetch();
|
||||||
|
// This stops Twitch from pausing the player when in another tab and an ad shows.
|
||||||
|
// Taken from https://github.com/saucettv/VideoAdBlockForTwitch/blob/cefce9d2b565769c77e3666ac8234c3acfe20d83/chrome/content.js#L30
|
||||||
|
try {
|
||||||
|
Object.defineProperty(document, 'visibilityState', {
|
||||||
|
get() {
|
||||||
|
return 'visible';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}catch{}
|
||||||
|
try {
|
||||||
|
Object.defineProperty(document, 'hidden', {
|
||||||
|
get() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}catch{}
|
||||||
|
var block = e => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
e.stopImmediatePropagation();
|
||||||
|
};
|
||||||
|
document.addEventListener('visibilitychange', block, true);
|
||||||
|
document.addEventListener('webkitvisibilitychange', block, true);
|
||||||
|
document.addEventListener('mozvisibilitychange', block, true);
|
||||||
|
document.addEventListener('hasFocus', block, true);
|
||||||
|
try {
|
||||||
|
if (/Firefox/.test(navigator.userAgent)) {
|
||||||
|
Object.defineProperty(document, 'mozHidden', {
|
||||||
|
get() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Object.defineProperty(document, 'webkitHidden', {
|
||||||
|
get() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}catch{}
|
||||||
|
}
|
||||||
|
if (document.readyState === "complete" || document.readyState === "loaded" || document.readyState === "interactive") {
|
||||||
|
onContentLoaded();
|
||||||
|
} else {
|
||||||
|
window.addEventListener("DOMContentLoaded", function() {
|
||||||
|
onContentLoaded();
|
||||||
|
});
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name TwitchAdSolutions (vaft)
|
// @name TwitchAdSolutions (vaft)
|
||||||
// @namespace https://github.com/pixeltris/TwitchAdSolutions
|
// @namespace https://github.com/pixeltris/TwitchAdSolutions
|
||||||
// @version 10.0.0
|
// @version 11.0.0
|
||||||
// @description Multiple solutions for blocking Twitch ads (vaft)
|
// @description Multiple solutions for blocking Twitch ads (vaft)
|
||||||
// @updateURL https://github.com/pixeltris/TwitchAdSolutions/raw/master/vaft/vaft.user.js
|
// @updateURL https://github.com/pixeltris/TwitchAdSolutions/raw/master/vaft/vaft.user.js
|
||||||
// @downloadURL https://github.com/pixeltris/TwitchAdSolutions/raw/master/vaft/vaft.user.js
|
// @downloadURL https://github.com/pixeltris/TwitchAdSolutions/raw/master/vaft/vaft.user.js
|
||||||
@ -13,48 +13,6 @@
|
|||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
(function() {
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
//This stops Twitch from pausing the player when in another tab and an ad shows.
|
|
||||||
try {
|
|
||||||
Object.defineProperty(document, 'visibilityState', {
|
|
||||||
get() {
|
|
||||||
return 'visible';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Object.defineProperty(document, 'hidden', {
|
|
||||||
get() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const block = e => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
e.stopImmediatePropagation();
|
|
||||||
};
|
|
||||||
const process = e => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
e.stopImmediatePropagation();
|
|
||||||
//This corrects the background tab buffer bug when switching to the background tab for the first time after an extended period.
|
|
||||||
doTwitchPlayerTask(false, false, true, false, false);
|
|
||||||
};
|
|
||||||
document.addEventListener('visibilitychange', block, true);
|
|
||||||
document.addEventListener('webkitvisibilitychange', block, true);
|
|
||||||
document.addEventListener('mozvisibilitychange', block, true);
|
|
||||||
document.addEventListener('hasFocus', block, true);
|
|
||||||
if (/Firefox/.test(navigator.userAgent)) {
|
|
||||||
Object.defineProperty(document, 'mozHidden', {
|
|
||||||
get() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
Object.defineProperty(document, 'webkitHidden', {
|
|
||||||
get() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (err) {}
|
|
||||||
function declareOptions(scope) {
|
function declareOptions(scope) {
|
||||||
scope.AdSignifier = 'stitched';
|
scope.AdSignifier = 'stitched';
|
||||||
scope.ClientID = 'kimne78kx3ncx6brgo4mv6wki5h1ko';
|
scope.ClientID = 'kimne78kx3ncx6brgo4mv6wki5h1ko';
|
||||||
@ -75,186 +33,187 @@
|
|||||||
scope.ClientIntegrityHeader = null;
|
scope.ClientIntegrityHeader = null;
|
||||||
scope.AuthorizationHeader = null;
|
scope.AuthorizationHeader = null;
|
||||||
}
|
}
|
||||||
declareOptions(window);
|
|
||||||
var twitchWorkers = [];
|
var twitchWorkers = [];
|
||||||
var adBlockDiv = null;
|
var adBlockDiv = null;
|
||||||
var OriginalVideoPlayerQuality = null;
|
var OriginalVideoPlayerQuality = null;
|
||||||
var IsPlayerAutoQuality = null;
|
var IsPlayerAutoQuality = null;
|
||||||
const oldWorker = window.Worker;
|
const oldWorker = window.Worker;
|
||||||
window.Worker = class Worker extends oldWorker {
|
function hookWindowWorker() {
|
||||||
constructor(twitchBlobUrl, options) {
|
window.Worker = class Worker extends oldWorker {
|
||||||
var isTwitchWorker = false;
|
constructor(twitchBlobUrl, options) {
|
||||||
try {
|
var isTwitchWorker = false;
|
||||||
isTwitchWorker = new URL(twitchBlobUrl).origin.endsWith('.twitch.tv');
|
try {
|
||||||
} catch {}
|
isTwitchWorker = new URL(twitchBlobUrl).origin.endsWith('.twitch.tv');
|
||||||
if (!isTwitchWorker) {
|
} catch {}
|
||||||
super(twitchBlobUrl, options);
|
if (!isTwitchWorker) {
|
||||||
return;
|
super(twitchBlobUrl, options);
|
||||||
}
|
return;
|
||||||
var newBlobStr = `
|
|
||||||
${getStreamUrlForResolution.toString()}
|
|
||||||
${getStreamForResolution.toString()}
|
|
||||||
${stripUnusedParams.toString()}
|
|
||||||
${processM3U8.toString()}
|
|
||||||
${hookWorkerFetch.toString()}
|
|
||||||
${declareOptions.toString()}
|
|
||||||
${getAccessToken.toString()}
|
|
||||||
${gqlRequest.toString()}
|
|
||||||
${adRecordgqlPacket.toString()}
|
|
||||||
${tryNotifyTwitch.toString()}
|
|
||||||
${parseAttributes.toString()}
|
|
||||||
${getWasmWorkerUrl.toString()}
|
|
||||||
var workerUrl = getWasmWorkerUrl('${twitchBlobUrl.replaceAll("'", "%27")}');
|
|
||||||
if (workerUrl && workerUrl.includes('assets.twitch.tv/assets/amazon-ivs-wasmworker')) {
|
|
||||||
declareOptions(self);
|
|
||||||
self.addEventListener('message', function(e) {
|
|
||||||
if (e.data.key == 'UpdateIsSquadStream') {
|
|
||||||
IsSquadStream = e.data.value;
|
|
||||||
} else if (e.data.key == 'UpdateClientVersion') {
|
|
||||||
ClientVersion = e.data.value;
|
|
||||||
} else if (e.data.key == 'UpdateClientSession') {
|
|
||||||
ClientSession = e.data.value;
|
|
||||||
} else if (e.data.key == 'UpdateClientId') {
|
|
||||||
ClientID = e.data.value;
|
|
||||||
} else if (e.data.key == 'UpdateDeviceId') {
|
|
||||||
GQLDeviceID = e.data.value;
|
|
||||||
} else if (e.data.key == 'UpdateClientIntegrityHeader') {
|
|
||||||
ClientIntegrityHeader = e.data.value;
|
|
||||||
} else if (e.data.key == 'UpdateAuthorizationHeader') {
|
|
||||||
AuthorizationHeader = e.data.value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
hookWorkerFetch();
|
|
||||||
importScripts(workerUrl);
|
|
||||||
}
|
}
|
||||||
`;
|
var newBlobStr = `
|
||||||
super(URL.createObjectURL(new Blob([newBlobStr])), options);
|
${getStreamUrlForResolution.toString()}
|
||||||
twitchWorkers.push(this);
|
${getStreamForResolution.toString()}
|
||||||
this.onmessage = function(e) {
|
${stripUnusedParams.toString()}
|
||||||
if (e.data.key == 'ShowAdBlockBanner') {
|
${processM3U8.toString()}
|
||||||
if (adBlockDiv == null) {
|
${hookWorkerFetch.toString()}
|
||||||
adBlockDiv = getAdBlockDiv();
|
${declareOptions.toString()}
|
||||||
|
${getAccessToken.toString()}
|
||||||
|
${gqlRequest.toString()}
|
||||||
|
${adRecordgqlPacket.toString()}
|
||||||
|
${tryNotifyTwitch.toString()}
|
||||||
|
${parseAttributes.toString()}
|
||||||
|
${getWasmWorkerUrl.toString()}
|
||||||
|
var workerUrl = getWasmWorkerUrl('${twitchBlobUrl.replaceAll("'", "%27")}');
|
||||||
|
if (workerUrl && workerUrl.includes('assets.twitch.tv/assets/amazon-ivs-wasmworker')) {
|
||||||
|
declareOptions(self);
|
||||||
|
self.addEventListener('message', function(e) {
|
||||||
|
if (e.data.key == 'UpdateIsSquadStream') {
|
||||||
|
IsSquadStream = e.data.value;
|
||||||
|
} else if (e.data.key == 'UpdateClientVersion') {
|
||||||
|
ClientVersion = e.data.value;
|
||||||
|
} else if (e.data.key == 'UpdateClientSession') {
|
||||||
|
ClientSession = e.data.value;
|
||||||
|
} else if (e.data.key == 'UpdateClientId') {
|
||||||
|
ClientID = e.data.value;
|
||||||
|
} else if (e.data.key == 'UpdateDeviceId') {
|
||||||
|
GQLDeviceID = e.data.value;
|
||||||
|
} else if (e.data.key == 'UpdateClientIntegrityHeader') {
|
||||||
|
ClientIntegrityHeader = e.data.value;
|
||||||
|
} else if (e.data.key == 'UpdateAuthorizationHeader') {
|
||||||
|
AuthorizationHeader = e.data.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
hookWorkerFetch();
|
||||||
|
importScripts(workerUrl);
|
||||||
}
|
}
|
||||||
adBlockDiv.P.textContent = 'Blocking ads';
|
`;
|
||||||
adBlockDiv.style.display = 'block';
|
super(URL.createObjectURL(new Blob([newBlobStr])), options);
|
||||||
} else if (e.data.key == 'HideAdBlockBanner') {
|
twitchWorkers.push(this);
|
||||||
if (adBlockDiv == null) {
|
this.onmessage = function(e) {
|
||||||
adBlockDiv = getAdBlockDiv();
|
if (e.data.key == 'ShowAdBlockBanner') {
|
||||||
}
|
if (adBlockDiv == null) {
|
||||||
adBlockDiv.style.display = 'none';
|
adBlockDiv = getAdBlockDiv();
|
||||||
} else if (e.data.key == 'PauseResumePlayer') {
|
|
||||||
doTwitchPlayerTask(true, false, false, false, false);
|
|
||||||
} else if (e.data.key == 'ForceChangeQuality') {
|
|
||||||
//This is used to fix the bug where the video would freeze.
|
|
||||||
try {
|
|
||||||
//if (navigator.userAgent.toLowerCase().indexOf('firefox') == -1) {
|
|
||||||
return;
|
|
||||||
//}
|
|
||||||
var autoQuality = doTwitchPlayerTask(false, false, false, true, false);
|
|
||||||
var currentQuality = doTwitchPlayerTask(false, true, false, false, false);
|
|
||||||
if (IsPlayerAutoQuality == null) {
|
|
||||||
IsPlayerAutoQuality = autoQuality;
|
|
||||||
}
|
}
|
||||||
if (OriginalVideoPlayerQuality == null) {
|
adBlockDiv.P.textContent = 'Blocking ads';
|
||||||
OriginalVideoPlayerQuality = currentQuality;
|
adBlockDiv.style.display = 'block';
|
||||||
|
} else if (e.data.key == 'HideAdBlockBanner') {
|
||||||
|
if (adBlockDiv == null) {
|
||||||
|
adBlockDiv = getAdBlockDiv();
|
||||||
}
|
}
|
||||||
if (!currentQuality.includes('360') || e.data.value != null) {
|
adBlockDiv.style.display = 'none';
|
||||||
if (!OriginalVideoPlayerQuality.includes('360')) {
|
} else if (e.data.key == 'PauseResumePlayer') {
|
||||||
var settingsMenu = document.querySelector('div[data-a-target="player-settings-menu"]');
|
doTwitchPlayerTask(true, false, false, false, false);
|
||||||
if (settingsMenu == null) {
|
} else if (e.data.key == 'ForceChangeQuality') {
|
||||||
var settingsCog = document.querySelector('button[data-a-target="player-settings-button"]');
|
//This is used to fix the bug where the video would freeze.
|
||||||
if (settingsCog) {
|
try {
|
||||||
settingsCog.click();
|
//if (navigator.userAgent.toLowerCase().indexOf('firefox') == -1) {
|
||||||
var qualityMenu = document.querySelector('button[data-a-target="player-settings-menu-item-quality"]');
|
return;
|
||||||
if (qualityMenu) {
|
//}
|
||||||
qualityMenu.click();
|
var autoQuality = doTwitchPlayerTask(false, false, false, true, false);
|
||||||
}
|
var currentQuality = doTwitchPlayerTask(false, true, false, false, false);
|
||||||
var lowQuality = document.querySelectorAll('input[data-a-target="tw-radio"');
|
if (IsPlayerAutoQuality == null) {
|
||||||
if (lowQuality) {
|
IsPlayerAutoQuality = autoQuality;
|
||||||
var qualityToSelect = lowQuality.length - 2;
|
}
|
||||||
if (e.data.value != null) {
|
if (OriginalVideoPlayerQuality == null) {
|
||||||
if (e.data.value.includes('original')) {
|
OriginalVideoPlayerQuality = currentQuality;
|
||||||
e.data.value = OriginalVideoPlayerQuality;
|
}
|
||||||
if (IsPlayerAutoQuality) {
|
if (!currentQuality.includes('360') || e.data.value != null) {
|
||||||
e.data.value = 'auto';
|
if (!OriginalVideoPlayerQuality.includes('360')) {
|
||||||
|
var settingsMenu = document.querySelector('div[data-a-target="player-settings-menu"]');
|
||||||
|
if (settingsMenu == null) {
|
||||||
|
var settingsCog = document.querySelector('button[data-a-target="player-settings-button"]');
|
||||||
|
if (settingsCog) {
|
||||||
|
settingsCog.click();
|
||||||
|
var qualityMenu = document.querySelector('button[data-a-target="player-settings-menu-item-quality"]');
|
||||||
|
if (qualityMenu) {
|
||||||
|
qualityMenu.click();
|
||||||
|
}
|
||||||
|
var lowQuality = document.querySelectorAll('input[data-a-target="tw-radio"');
|
||||||
|
if (lowQuality) {
|
||||||
|
var qualityToSelect = lowQuality.length - 2;
|
||||||
|
if (e.data.value != null) {
|
||||||
|
if (e.data.value.includes('original')) {
|
||||||
|
e.data.value = OriginalVideoPlayerQuality;
|
||||||
|
if (IsPlayerAutoQuality) {
|
||||||
|
e.data.value = 'auto';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (e.data.value.includes('160p')) {
|
||||||
|
qualityToSelect = 5;
|
||||||
|
}
|
||||||
|
if (e.data.value.includes('360p')) {
|
||||||
|
qualityToSelect = 4;
|
||||||
|
}
|
||||||
|
if (e.data.value.includes('480p')) {
|
||||||
|
qualityToSelect = 3;
|
||||||
|
}
|
||||||
|
if (e.data.value.includes('720p')) {
|
||||||
|
qualityToSelect = 2;
|
||||||
|
}
|
||||||
|
if (e.data.value.includes('822p')) {
|
||||||
|
qualityToSelect = 2;
|
||||||
|
}
|
||||||
|
if (e.data.value.includes('864p')) {
|
||||||
|
qualityToSelect = 2;
|
||||||
|
}
|
||||||
|
if (e.data.value.includes('900p')) {
|
||||||
|
qualityToSelect = 2;
|
||||||
|
}
|
||||||
|
if (e.data.value.includes('936p')) {
|
||||||
|
qualityToSelect = 2;
|
||||||
|
}
|
||||||
|
if (e.data.value.includes('960p')) {
|
||||||
|
qualityToSelect = 2;
|
||||||
|
}
|
||||||
|
if (e.data.value.includes('1080p')) {
|
||||||
|
qualityToSelect = 2;
|
||||||
|
}
|
||||||
|
if (e.data.value.includes('source')) {
|
||||||
|
qualityToSelect = 1;
|
||||||
|
}
|
||||||
|
if (e.data.value.includes('auto')) {
|
||||||
|
qualityToSelect = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (e.data.value.includes('160p')) {
|
var currentQualityLS = window.localStorage.getItem('video-quality');
|
||||||
qualityToSelect = 5;
|
lowQuality[qualityToSelect].click();
|
||||||
|
settingsCog.click();
|
||||||
|
window.localStorage.setItem('video-quality', currentQualityLS);
|
||||||
|
if (e.data.value != null) {
|
||||||
|
OriginalVideoPlayerQuality = null;
|
||||||
|
IsPlayerAutoQuality = null;
|
||||||
|
doTwitchPlayerTask(false, false, false, true, true);
|
||||||
}
|
}
|
||||||
if (e.data.value.includes('360p')) {
|
|
||||||
qualityToSelect = 4;
|
|
||||||
}
|
|
||||||
if (e.data.value.includes('480p')) {
|
|
||||||
qualityToSelect = 3;
|
|
||||||
}
|
|
||||||
if (e.data.value.includes('720p')) {
|
|
||||||
qualityToSelect = 2;
|
|
||||||
}
|
|
||||||
if (e.data.value.includes('822p')) {
|
|
||||||
qualityToSelect = 2;
|
|
||||||
}
|
|
||||||
if (e.data.value.includes('864p')) {
|
|
||||||
qualityToSelect = 2;
|
|
||||||
}
|
|
||||||
if (e.data.value.includes('900p')) {
|
|
||||||
qualityToSelect = 2;
|
|
||||||
}
|
|
||||||
if (e.data.value.includes('936p')) {
|
|
||||||
qualityToSelect = 2;
|
|
||||||
}
|
|
||||||
if (e.data.value.includes('960p')) {
|
|
||||||
qualityToSelect = 2;
|
|
||||||
}
|
|
||||||
if (e.data.value.includes('1080p')) {
|
|
||||||
qualityToSelect = 2;
|
|
||||||
}
|
|
||||||
if (e.data.value.includes('source')) {
|
|
||||||
qualityToSelect = 1;
|
|
||||||
}
|
|
||||||
if (e.data.value.includes('auto')) {
|
|
||||||
qualityToSelect = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var currentQualityLS = window.localStorage.getItem('video-quality');
|
|
||||||
lowQuality[qualityToSelect].click();
|
|
||||||
settingsCog.click();
|
|
||||||
window.localStorage.setItem('video-quality', currentQualityLS);
|
|
||||||
if (e.data.value != null) {
|
|
||||||
OriginalVideoPlayerQuality = null;
|
|
||||||
IsPlayerAutoQuality = null;
|
|
||||||
doTwitchPlayerTask(false, false, false, true, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (err) {
|
||||||
|
OriginalVideoPlayerQuality = null;
|
||||||
|
IsPlayerAutoQuality = null;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
|
||||||
OriginalVideoPlayerQuality = null;
|
|
||||||
IsPlayerAutoQuality = null;
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
function getAdBlockDiv() {
|
||||||
function getAdBlockDiv() {
|
//To display a notification to the user, that an ad is being blocked.
|
||||||
//To display a notification to the user, that an ad is being blocked.
|
var playerRootDiv = document.querySelector('.video-player');
|
||||||
var playerRootDiv = document.querySelector('.video-player');
|
var adBlockDiv = null;
|
||||||
var adBlockDiv = null;
|
if (playerRootDiv != null) {
|
||||||
if (playerRootDiv != null) {
|
adBlockDiv = playerRootDiv.querySelector('.adblock-overlay');
|
||||||
adBlockDiv = playerRootDiv.querySelector('.adblock-overlay');
|
if (adBlockDiv == null) {
|
||||||
if (adBlockDiv == null) {
|
adBlockDiv = document.createElement('div');
|
||||||
adBlockDiv = document.createElement('div');
|
adBlockDiv.className = 'adblock-overlay';
|
||||||
adBlockDiv.className = 'adblock-overlay';
|
adBlockDiv.innerHTML = '<div class="player-adblock-notice" style="color: white; background-color: rgba(0, 0, 0, 0.8); position: absolute; top: 0px; left: 0px; padding: 5px;"><p></p></div>';
|
||||||
adBlockDiv.innerHTML = '<div class="player-adblock-notice" style="color: white; background-color: rgba(0, 0, 0, 0.8); position: absolute; top: 0px; left: 0px; padding: 5px;"><p></p></div>';
|
adBlockDiv.style.display = 'none';
|
||||||
adBlockDiv.style.display = 'none';
|
adBlockDiv.P = adBlockDiv.querySelector('p');
|
||||||
adBlockDiv.P = adBlockDiv.querySelector('p');
|
playerRootDiv.appendChild(adBlockDiv);
|
||||||
playerRootDiv.appendChild(adBlockDiv);
|
}
|
||||||
}
|
}
|
||||||
|
return adBlockDiv;
|
||||||
}
|
}
|
||||||
return adBlockDiv;
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
}
|
||||||
function getWasmWorkerUrl(twitchBlobUrl) {
|
function getWasmWorkerUrl(twitchBlobUrl) {
|
||||||
var req = new XMLHttpRequest();
|
var req = new XMLHttpRequest();
|
||||||
req.open('GET', twitchBlobUrl, false);
|
req.open('GET', twitchBlobUrl, false);
|
||||||
@ -865,5 +824,73 @@
|
|||||||
return realFetch.apply(this, arguments);
|
return realFetch.apply(this, arguments);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
hookFetch();
|
function isWorkerIntact() {
|
||||||
|
// Taken from Adguard Extra
|
||||||
|
const iframe = window.document.createElement('iframe');
|
||||||
|
window.document.body.append(iframe);
|
||||||
|
const cleanWindow = iframe.contentWindow;
|
||||||
|
if (cleanWindow.Worker.toString() === window.Worker.toString()) {
|
||||||
|
iframe.remove();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
iframe.remove();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
function onContentLoaded() {
|
||||||
|
if (!isWorkerIntact()) {
|
||||||
|
console.log('Twitch Worker is already hooked');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.reloadTwitchPlayer = reloadTwitchPlayer;
|
||||||
|
declareOptions(window);
|
||||||
|
hookWindowWorker();
|
||||||
|
hookFetch();
|
||||||
|
// This stops Twitch from pausing the player when in another tab and an ad shows.
|
||||||
|
// Taken from https://github.com/saucettv/VideoAdBlockForTwitch/blob/cefce9d2b565769c77e3666ac8234c3acfe20d83/chrome/content.js#L30
|
||||||
|
try {
|
||||||
|
Object.defineProperty(document, 'visibilityState', {
|
||||||
|
get() {
|
||||||
|
return 'visible';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}catch{}
|
||||||
|
try {
|
||||||
|
Object.defineProperty(document, 'hidden', {
|
||||||
|
get() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}catch{}
|
||||||
|
var block = e => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
e.stopImmediatePropagation();
|
||||||
|
};
|
||||||
|
document.addEventListener('visibilitychange', block, true);
|
||||||
|
document.addEventListener('webkitvisibilitychange', block, true);
|
||||||
|
document.addEventListener('mozvisibilitychange', block, true);
|
||||||
|
document.addEventListener('hasFocus', block, true);
|
||||||
|
try {
|
||||||
|
if (/Firefox/.test(navigator.userAgent)) {
|
||||||
|
Object.defineProperty(document, 'mozHidden', {
|
||||||
|
get() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Object.defineProperty(document, 'webkitHidden', {
|
||||||
|
get() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}catch{}
|
||||||
|
}
|
||||||
|
if (document.readyState === "complete" || document.readyState === "loaded" || document.readyState === "interactive") {
|
||||||
|
onContentLoaded();
|
||||||
|
} else {
|
||||||
|
window.addEventListener("DOMContentLoaded", function() {
|
||||||
|
onContentLoaded();
|
||||||
|
});
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
|
@ -23,89 +23,90 @@ twitch-videoad.js text/javascript
|
|||||||
scope.ClientIntegrityHeader = null;
|
scope.ClientIntegrityHeader = null;
|
||||||
scope.AuthorizationHeader = null;
|
scope.AuthorizationHeader = null;
|
||||||
}
|
}
|
||||||
declareOptions(window);
|
|
||||||
var twitchWorkers = [];
|
var twitchWorkers = [];
|
||||||
const oldWorker = window.Worker;
|
const oldWorker = window.Worker;
|
||||||
window.Worker = class Worker extends oldWorker {
|
function hookWindowWorker() {
|
||||||
constructor(twitchBlobUrl, options) {
|
window.Worker = class Worker extends oldWorker {
|
||||||
var isTwitchWorker = false;
|
constructor(twitchBlobUrl, options) {
|
||||||
try {
|
var isTwitchWorker = false;
|
||||||
isTwitchWorker = new URL(twitchBlobUrl).origin.endsWith('.twitch.tv');
|
try {
|
||||||
} catch {}
|
isTwitchWorker = new URL(twitchBlobUrl).origin.endsWith('.twitch.tv');
|
||||||
if (!isTwitchWorker) {
|
} catch {}
|
||||||
super(twitchBlobUrl, options);
|
if (!isTwitchWorker) {
|
||||||
return;
|
super(twitchBlobUrl, options);
|
||||||
}
|
return;
|
||||||
var newBlobStr = `
|
|
||||||
${processM3U8.toString()}
|
|
||||||
${hookWorkerFetch.toString()}
|
|
||||||
${declareOptions.toString()}
|
|
||||||
${getAccessToken.toString()}
|
|
||||||
${gqlRequest.toString()}
|
|
||||||
${makeGraphQlPacket.toString()}
|
|
||||||
${tryNotifyAdsWatchedM3U8.toString()}
|
|
||||||
${parseAttributes.toString()}
|
|
||||||
${onFoundAd.toString()}
|
|
||||||
${getWasmWorkerUrl.toString()}
|
|
||||||
var workerUrl = getWasmWorkerUrl('${twitchBlobUrl.replaceAll("'", "%27")}');
|
|
||||||
if (workerUrl && workerUrl.includes('assets.twitch.tv/assets/amazon-ivs-wasmworker')) {
|
|
||||||
declareOptions(self);
|
|
||||||
self.addEventListener('message', function(e) {
|
|
||||||
if (e.data.key == 'UboUpdateDeviceId') {
|
|
||||||
gql_device_id = e.data.value;
|
|
||||||
} else if (e.data.key == 'UpdateClientIntegrityHeader') {
|
|
||||||
ClientIntegrityHeader = e.data.value;
|
|
||||||
} else if (e.data.key == 'UpdateAuthorizationHeader') {
|
|
||||||
AuthorizationHeader = e.data.value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
hookWorkerFetch();
|
|
||||||
importScripts(workerUrl);
|
|
||||||
}
|
}
|
||||||
`
|
var newBlobStr = `
|
||||||
super(URL.createObjectURL(new Blob([newBlobStr])), options);
|
${processM3U8.toString()}
|
||||||
twitchWorkers.push(this);
|
${hookWorkerFetch.toString()}
|
||||||
this.onmessage = function(e) {
|
${declareOptions.toString()}
|
||||||
// NOTE: Removed adDiv caching as '.video-player' can change between streams?
|
${getAccessToken.toString()}
|
||||||
if (e.data.key == 'UboShowAdBanner') {
|
${gqlRequest.toString()}
|
||||||
var adDiv = getAdDiv();
|
${makeGraphQlPacket.toString()}
|
||||||
if (adDiv != null) {
|
${tryNotifyAdsWatchedM3U8.toString()}
|
||||||
adDiv.P.textContent = 'Blocking' + (e.data.isMidroll ? ' midroll' : '') + ' ads';
|
${parseAttributes.toString()}
|
||||||
if (OPT_SHOW_AD_BANNER) {
|
${onFoundAd.toString()}
|
||||||
adDiv.style.display = 'block';
|
${getWasmWorkerUrl.toString()}
|
||||||
|
var workerUrl = getWasmWorkerUrl('${twitchBlobUrl.replaceAll("'", "%27")}');
|
||||||
|
if (workerUrl && workerUrl.includes('assets.twitch.tv/assets/amazon-ivs-wasmworker')) {
|
||||||
|
declareOptions(self);
|
||||||
|
self.addEventListener('message', function(e) {
|
||||||
|
if (e.data.key == 'UboUpdateDeviceId') {
|
||||||
|
gql_device_id = e.data.value;
|
||||||
|
} else if (e.data.key == 'UpdateClientIntegrityHeader') {
|
||||||
|
ClientIntegrityHeader = e.data.value;
|
||||||
|
} else if (e.data.key == 'UpdateAuthorizationHeader') {
|
||||||
|
AuthorizationHeader = e.data.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
hookWorkerFetch();
|
||||||
|
importScripts(workerUrl);
|
||||||
|
}
|
||||||
|
`
|
||||||
|
super(URL.createObjectURL(new Blob([newBlobStr])), options);
|
||||||
|
twitchWorkers.push(this);
|
||||||
|
this.onmessage = function(e) {
|
||||||
|
// NOTE: Removed adDiv caching as '.video-player' can change between streams?
|
||||||
|
if (e.data.key == 'UboShowAdBanner') {
|
||||||
|
var adDiv = getAdDiv();
|
||||||
|
if (adDiv != null) {
|
||||||
|
adDiv.P.textContent = 'Blocking' + (e.data.isMidroll ? ' midroll' : '') + ' ads';
|
||||||
|
if (OPT_SHOW_AD_BANNER) {
|
||||||
|
adDiv.style.display = 'block';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (e.data.key == 'UboHideAdBanner') {
|
||||||
|
var adDiv = getAdDiv();
|
||||||
|
if (adDiv != null) {
|
||||||
|
adDiv.style.display = 'none';
|
||||||
|
}
|
||||||
|
} else if (e.data.key == 'UboChannelNameM3U8Changed') {
|
||||||
|
//console.log('M3U8 channel name changed to ' + e.data.value);
|
||||||
|
} else if (e.data.key == 'UboReloadPlayer') {
|
||||||
|
reloadTwitchPlayer();
|
||||||
|
} else if (e.data.key == 'UboPauseResumePlayer') {
|
||||||
|
reloadTwitchPlayer(false, true);
|
||||||
|
} else if (e.data.key == 'UboSeekPlayer') {
|
||||||
|
reloadTwitchPlayer(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function getAdDiv() {
|
||||||
|
var playerRootDiv = document.querySelector('.video-player');
|
||||||
|
var adDiv = null;
|
||||||
|
if (playerRootDiv != null) {
|
||||||
|
adDiv = playerRootDiv.querySelector('.ubo-overlay');
|
||||||
|
if (adDiv == null) {
|
||||||
|
adDiv = document.createElement('div');
|
||||||
|
adDiv.className = 'ubo-overlay';
|
||||||
|
adDiv.innerHTML = '<div class="player-ad-notice" style="color: white; background-color: rgba(0, 0, 0, 0.8); position: absolute; top: 0px; left: 0px; padding: 5px;"><p></p></div>';
|
||||||
|
adDiv.style.display = 'none';
|
||||||
|
adDiv.P = adDiv.querySelector('p');
|
||||||
|
playerRootDiv.appendChild(adDiv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (e.data.key == 'UboHideAdBanner') {
|
return adDiv;
|
||||||
var adDiv = getAdDiv();
|
|
||||||
if (adDiv != null) {
|
|
||||||
adDiv.style.display = 'none';
|
|
||||||
}
|
|
||||||
} else if (e.data.key == 'UboChannelNameM3U8Changed') {
|
|
||||||
//console.log('M3U8 channel name changed to ' + e.data.value);
|
|
||||||
} else if (e.data.key == 'UboReloadPlayer') {
|
|
||||||
reloadTwitchPlayer();
|
|
||||||
} else if (e.data.key == 'UboPauseResumePlayer') {
|
|
||||||
reloadTwitchPlayer(false, true);
|
|
||||||
} else if (e.data.key == 'UboSeekPlayer') {
|
|
||||||
reloadTwitchPlayer(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function getAdDiv() {
|
|
||||||
var playerRootDiv = document.querySelector('.video-player');
|
|
||||||
var adDiv = null;
|
|
||||||
if (playerRootDiv != null) {
|
|
||||||
adDiv = playerRootDiv.querySelector('.ubo-overlay');
|
|
||||||
if (adDiv == null) {
|
|
||||||
adDiv = document.createElement('div');
|
|
||||||
adDiv.className = 'ubo-overlay';
|
|
||||||
adDiv.innerHTML = '<div class="player-ad-notice" style="color: white; background-color: rgba(0, 0, 0, 0.8); position: absolute; top: 0px; left: 0px; padding: 5px;"><p></p></div>';
|
|
||||||
adDiv.style.display = 'none';
|
|
||||||
adDiv.P = adDiv.querySelector('p');
|
|
||||||
playerRootDiv.appendChild(adDiv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return adDiv;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function getWasmWorkerUrl(twitchBlobUrl) {
|
function getWasmWorkerUrl(twitchBlobUrl) {
|
||||||
@ -580,9 +581,27 @@ twitch-videoad.js text/javascript
|
|||||||
localStorage.setItem(lsKeyVolume, currentVolumeLS);
|
localStorage.setItem(lsKeyVolume, currentVolumeLS);
|
||||||
}, 3000);
|
}, 3000);
|
||||||
}
|
}
|
||||||
window.reloadTwitchPlayer = reloadTwitchPlayer;
|
function isWorkerIntact() {
|
||||||
hookFetch();
|
// Taken from Adguard Extra
|
||||||
|
const iframe = window.document.createElement('iframe');
|
||||||
|
window.document.body.append(iframe);
|
||||||
|
const cleanWindow = iframe.contentWindow;
|
||||||
|
if (cleanWindow.Worker.toString() === window.Worker.toString()) {
|
||||||
|
iframe.remove();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
iframe.remove();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
function onContentLoaded() {
|
function onContentLoaded() {
|
||||||
|
if (!isWorkerIntact()) {
|
||||||
|
console.log('Twitch Worker is already hooked');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.reloadTwitchPlayer = reloadTwitchPlayer;
|
||||||
|
declareOptions(window);
|
||||||
|
hookWindowWorker();
|
||||||
|
hookFetch();
|
||||||
// This stops Twitch from pausing the player when in another tab and an ad shows.
|
// This stops Twitch from pausing the player when in another tab and an ad shows.
|
||||||
// Taken from https://github.com/saucettv/VideoAdBlockForTwitch/blob/cefce9d2b565769c77e3666ac8234c3acfe20d83/chrome/content.js#L30
|
// Taken from https://github.com/saucettv/VideoAdBlockForTwitch/blob/cefce9d2b565769c77e3666ac8234c3acfe20d83/chrome/content.js#L30
|
||||||
try {
|
try {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name TwitchAdSolutions (video-swap-new)
|
// @name TwitchAdSolutions (video-swap-new)
|
||||||
// @namespace https://github.com/pixeltris/TwitchAdSolutions
|
// @namespace https://github.com/pixeltris/TwitchAdSolutions
|
||||||
// @version 1.28
|
// @version 1.29
|
||||||
// @updateURL https://github.com/pixeltris/TwitchAdSolutions/raw/master/video-swap-new/video-swap-new.user.js
|
// @updateURL https://github.com/pixeltris/TwitchAdSolutions/raw/master/video-swap-new/video-swap-new.user.js
|
||||||
// @downloadURL https://github.com/pixeltris/TwitchAdSolutions/raw/master/video-swap-new/video-swap-new.user.js
|
// @downloadURL https://github.com/pixeltris/TwitchAdSolutions/raw/master/video-swap-new/video-swap-new.user.js
|
||||||
// @description Multiple solutions for blocking Twitch ads (video-swap-new)
|
// @description Multiple solutions for blocking Twitch ads (video-swap-new)
|
||||||
@ -35,89 +35,90 @@
|
|||||||
scope.ClientIntegrityHeader = null;
|
scope.ClientIntegrityHeader = null;
|
||||||
scope.AuthorizationHeader = null;
|
scope.AuthorizationHeader = null;
|
||||||
}
|
}
|
||||||
declareOptions(window);
|
|
||||||
var twitchWorkers = [];
|
var twitchWorkers = [];
|
||||||
const oldWorker = window.Worker;
|
const oldWorker = window.Worker;
|
||||||
window.Worker = class Worker extends oldWorker {
|
function hookWindowWorker() {
|
||||||
constructor(twitchBlobUrl, options) {
|
window.Worker = class Worker extends oldWorker {
|
||||||
var isTwitchWorker = false;
|
constructor(twitchBlobUrl, options) {
|
||||||
try {
|
var isTwitchWorker = false;
|
||||||
isTwitchWorker = new URL(twitchBlobUrl).origin.endsWith('.twitch.tv');
|
try {
|
||||||
} catch {}
|
isTwitchWorker = new URL(twitchBlobUrl).origin.endsWith('.twitch.tv');
|
||||||
if (!isTwitchWorker) {
|
} catch {}
|
||||||
super(twitchBlobUrl, options);
|
if (!isTwitchWorker) {
|
||||||
return;
|
super(twitchBlobUrl, options);
|
||||||
}
|
return;
|
||||||
var newBlobStr = `
|
|
||||||
${processM3U8.toString()}
|
|
||||||
${hookWorkerFetch.toString()}
|
|
||||||
${declareOptions.toString()}
|
|
||||||
${getAccessToken.toString()}
|
|
||||||
${gqlRequest.toString()}
|
|
||||||
${makeGraphQlPacket.toString()}
|
|
||||||
${tryNotifyAdsWatchedM3U8.toString()}
|
|
||||||
${parseAttributes.toString()}
|
|
||||||
${onFoundAd.toString()}
|
|
||||||
${getWasmWorkerUrl.toString()}
|
|
||||||
var workerUrl = getWasmWorkerUrl('${twitchBlobUrl.replaceAll("'", "%27")}');
|
|
||||||
if (workerUrl && workerUrl.includes('assets.twitch.tv/assets/amazon-ivs-wasmworker')) {
|
|
||||||
declareOptions(self);
|
|
||||||
self.addEventListener('message', function(e) {
|
|
||||||
if (e.data.key == 'UboUpdateDeviceId') {
|
|
||||||
gql_device_id = e.data.value;
|
|
||||||
} else if (e.data.key == 'UpdateClientIntegrityHeader') {
|
|
||||||
ClientIntegrityHeader = e.data.value;
|
|
||||||
} else if (e.data.key == 'UpdateAuthorizationHeader') {
|
|
||||||
AuthorizationHeader = e.data.value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
hookWorkerFetch();
|
|
||||||
importScripts(workerUrl);
|
|
||||||
}
|
}
|
||||||
`
|
var newBlobStr = `
|
||||||
super(URL.createObjectURL(new Blob([newBlobStr])), options);
|
${processM3U8.toString()}
|
||||||
twitchWorkers.push(this);
|
${hookWorkerFetch.toString()}
|
||||||
this.onmessage = function(e) {
|
${declareOptions.toString()}
|
||||||
// NOTE: Removed adDiv caching as '.video-player' can change between streams?
|
${getAccessToken.toString()}
|
||||||
if (e.data.key == 'UboShowAdBanner') {
|
${gqlRequest.toString()}
|
||||||
var adDiv = getAdDiv();
|
${makeGraphQlPacket.toString()}
|
||||||
if (adDiv != null) {
|
${tryNotifyAdsWatchedM3U8.toString()}
|
||||||
adDiv.P.textContent = 'Blocking' + (e.data.isMidroll ? ' midroll' : '') + ' ads';
|
${parseAttributes.toString()}
|
||||||
if (OPT_SHOW_AD_BANNER) {
|
${onFoundAd.toString()}
|
||||||
adDiv.style.display = 'block';
|
${getWasmWorkerUrl.toString()}
|
||||||
|
var workerUrl = getWasmWorkerUrl('${twitchBlobUrl.replaceAll("'", "%27")}');
|
||||||
|
if (workerUrl && workerUrl.includes('assets.twitch.tv/assets/amazon-ivs-wasmworker')) {
|
||||||
|
declareOptions(self);
|
||||||
|
self.addEventListener('message', function(e) {
|
||||||
|
if (e.data.key == 'UboUpdateDeviceId') {
|
||||||
|
gql_device_id = e.data.value;
|
||||||
|
} else if (e.data.key == 'UpdateClientIntegrityHeader') {
|
||||||
|
ClientIntegrityHeader = e.data.value;
|
||||||
|
} else if (e.data.key == 'UpdateAuthorizationHeader') {
|
||||||
|
AuthorizationHeader = e.data.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
hookWorkerFetch();
|
||||||
|
importScripts(workerUrl);
|
||||||
|
}
|
||||||
|
`
|
||||||
|
super(URL.createObjectURL(new Blob([newBlobStr])), options);
|
||||||
|
twitchWorkers.push(this);
|
||||||
|
this.onmessage = function(e) {
|
||||||
|
// NOTE: Removed adDiv caching as '.video-player' can change between streams?
|
||||||
|
if (e.data.key == 'UboShowAdBanner') {
|
||||||
|
var adDiv = getAdDiv();
|
||||||
|
if (adDiv != null) {
|
||||||
|
adDiv.P.textContent = 'Blocking' + (e.data.isMidroll ? ' midroll' : '') + ' ads';
|
||||||
|
if (OPT_SHOW_AD_BANNER) {
|
||||||
|
adDiv.style.display = 'block';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (e.data.key == 'UboHideAdBanner') {
|
||||||
|
var adDiv = getAdDiv();
|
||||||
|
if (adDiv != null) {
|
||||||
|
adDiv.style.display = 'none';
|
||||||
|
}
|
||||||
|
} else if (e.data.key == 'UboChannelNameM3U8Changed') {
|
||||||
|
//console.log('M3U8 channel name changed to ' + e.data.value);
|
||||||
|
} else if (e.data.key == 'UboReloadPlayer') {
|
||||||
|
reloadTwitchPlayer();
|
||||||
|
} else if (e.data.key == 'UboPauseResumePlayer') {
|
||||||
|
reloadTwitchPlayer(false, true);
|
||||||
|
} else if (e.data.key == 'UboSeekPlayer') {
|
||||||
|
reloadTwitchPlayer(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function getAdDiv() {
|
||||||
|
var playerRootDiv = document.querySelector('.video-player');
|
||||||
|
var adDiv = null;
|
||||||
|
if (playerRootDiv != null) {
|
||||||
|
adDiv = playerRootDiv.querySelector('.ubo-overlay');
|
||||||
|
if (adDiv == null) {
|
||||||
|
adDiv = document.createElement('div');
|
||||||
|
adDiv.className = 'ubo-overlay';
|
||||||
|
adDiv.innerHTML = '<div class="player-ad-notice" style="color: white; background-color: rgba(0, 0, 0, 0.8); position: absolute; top: 0px; left: 0px; padding: 5px;"><p></p></div>';
|
||||||
|
adDiv.style.display = 'none';
|
||||||
|
adDiv.P = adDiv.querySelector('p');
|
||||||
|
playerRootDiv.appendChild(adDiv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (e.data.key == 'UboHideAdBanner') {
|
return adDiv;
|
||||||
var adDiv = getAdDiv();
|
|
||||||
if (adDiv != null) {
|
|
||||||
adDiv.style.display = 'none';
|
|
||||||
}
|
|
||||||
} else if (e.data.key == 'UboChannelNameM3U8Changed') {
|
|
||||||
//console.log('M3U8 channel name changed to ' + e.data.value);
|
|
||||||
} else if (e.data.key == 'UboReloadPlayer') {
|
|
||||||
reloadTwitchPlayer();
|
|
||||||
} else if (e.data.key == 'UboPauseResumePlayer') {
|
|
||||||
reloadTwitchPlayer(false, true);
|
|
||||||
} else if (e.data.key == 'UboSeekPlayer') {
|
|
||||||
reloadTwitchPlayer(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function getAdDiv() {
|
|
||||||
var playerRootDiv = document.querySelector('.video-player');
|
|
||||||
var adDiv = null;
|
|
||||||
if (playerRootDiv != null) {
|
|
||||||
adDiv = playerRootDiv.querySelector('.ubo-overlay');
|
|
||||||
if (adDiv == null) {
|
|
||||||
adDiv = document.createElement('div');
|
|
||||||
adDiv.className = 'ubo-overlay';
|
|
||||||
adDiv.innerHTML = '<div class="player-ad-notice" style="color: white; background-color: rgba(0, 0, 0, 0.8); position: absolute; top: 0px; left: 0px; padding: 5px;"><p></p></div>';
|
|
||||||
adDiv.style.display = 'none';
|
|
||||||
adDiv.P = adDiv.querySelector('p');
|
|
||||||
playerRootDiv.appendChild(adDiv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return adDiv;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function getWasmWorkerUrl(twitchBlobUrl) {
|
function getWasmWorkerUrl(twitchBlobUrl) {
|
||||||
@ -592,9 +593,27 @@
|
|||||||
localStorage.setItem(lsKeyVolume, currentVolumeLS);
|
localStorage.setItem(lsKeyVolume, currentVolumeLS);
|
||||||
}, 3000);
|
}, 3000);
|
||||||
}
|
}
|
||||||
window.reloadTwitchPlayer = reloadTwitchPlayer;
|
function isWorkerIntact() {
|
||||||
hookFetch();
|
// Taken from Adguard Extra
|
||||||
|
const iframe = window.document.createElement('iframe');
|
||||||
|
window.document.body.append(iframe);
|
||||||
|
const cleanWindow = iframe.contentWindow;
|
||||||
|
if (cleanWindow.Worker.toString() === window.Worker.toString()) {
|
||||||
|
iframe.remove();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
iframe.remove();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
function onContentLoaded() {
|
function onContentLoaded() {
|
||||||
|
if (!isWorkerIntact()) {
|
||||||
|
console.log('Twitch Worker is already hooked');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.reloadTwitchPlayer = reloadTwitchPlayer;
|
||||||
|
declareOptions(window);
|
||||||
|
hookWindowWorker();
|
||||||
|
hookFetch();
|
||||||
// This stops Twitch from pausing the player when in another tab and an ad shows.
|
// This stops Twitch from pausing the player when in another tab and an ad shows.
|
||||||
// Taken from https://github.com/saucettv/VideoAdBlockForTwitch/blob/cefce9d2b565769c77e3666ac8234c3acfe20d83/chrome/content.js#L30
|
// Taken from https://github.com/saucettv/VideoAdBlockForTwitch/blob/cefce9d2b565769c77e3666ac8234c3acfe20d83/chrome/content.js#L30
|
||||||
try {
|
try {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user