1
0
mirror of https://github.com/pixeltris/TwitchAdSolutions.git synced 2024-11-25 11:52:52 +01:00

Fix preroll on every page refresh #188

This commit is contained in:
pixeltris 2023-10-11 11:08:30 +01:00
parent e8ff2b03a5
commit a285eeda50
4 changed files with 130 additions and 48 deletions

View File

@ -311,6 +311,7 @@ twitch-videoad.js text/javascript
StreamInfos[channelName] = streamInfo = {}; StreamInfos[channelName] = streamInfo = {};
} }
streamInfo.ChannelName = channelName; streamInfo.ChannelName = channelName;
streamInfo.RequestedAds = new Set();
streamInfo.Urls = [];// xxx.m3u8 -> { Resolution: "284x160", FrameRate: 30.0 } streamInfo.Urls = [];// xxx.m3u8 -> { Resolution: "284x160", FrameRate: 30.0 }
streamInfo.EncodingsM3U8Cache = []; streamInfo.EncodingsM3U8Cache = [];
streamInfo.EncodingsM3U8 = encodingsM3u8; streamInfo.EncodingsM3U8 = encodingsM3u8;
@ -471,6 +472,21 @@ twitch-videoad.js text/javascript
var isMidroll = textStr.includes('"MIDROLL"') || textStr.includes('"midroll"'); var isMidroll = textStr.includes('"MIDROLL"') || textStr.includes('"midroll"');
//Reduces ad frequency. TODO: Reduce the number of requests. This is really spamming Twitch with requests. //Reduces ad frequency. TODO: Reduce the number of requests. This is really spamming Twitch with requests.
if (!isMidroll) { if (!isMidroll) {
if (playerType === PlayerType2) {
var lines = textStr.replace('\r', '').split('\n');
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
if (line.startsWith('#EXTINF') && lines.length > i + 1) {
if (!line.includes(',live') && !streamInfo.RequestedAds.has(lines[i + 1])) {
// Only request one .ts file per .m3u8 request to avoid making too many requests
//console.log('Fetch ad .ts file');
streamInfo.RequestedAds.add(lines[i + 1]);
fetch(lines[i + 1]).then((response)=>{response.blob()});
break;
}
}
}
}
try { try {
//tryNotifyTwitch(textStr); //tryNotifyTwitch(textStr);
} catch (err) {} } catch (err) {}
@ -658,7 +674,7 @@ twitch-videoad.js text/javascript
} }
function gqlRequest(body, realFetch) { function gqlRequest(body, realFetch) {
if (ClientIntegrityHeader == null) { if (ClientIntegrityHeader == null) {
console.warn('ClientIntegrityHeader is null'); //console.warn('ClientIntegrityHeader is null');
//throw 'ClientIntegrityHeader is null'; //throw 'ClientIntegrityHeader is null';
} }
var fetchFunc = realFetch ? realFetch : fetch; var fetchFunc = realFetch ? realFetch : fetch;
@ -856,17 +872,21 @@ twitch-videoad.js text/javascript
} }
//Client integrity header //Client integrity header
ClientIntegrityHeader = init.headers['Client-Integrity']; ClientIntegrityHeader = init.headers['Client-Integrity'];
if (ClientIntegrityHeader && twitchMainWorker) {
twitchMainWorker.postMessage({ twitchMainWorker.postMessage({
key: 'UpdateClientIntegrityHeader', key: 'UpdateClientIntegrityHeader',
value: init.headers['Client-Integrity'] value: init.headers['Client-Integrity']
}); });
}
//Authorization header //Authorization header
AuthorizationHeader = init.headers['Authorization']; AuthorizationHeader = init.headers['Authorization'];
if (AuthorizationHeader && twitchMainWorker) {
twitchMainWorker.postMessage({ twitchMainWorker.postMessage({
key: 'UpdateAuthorizationHeader', key: 'UpdateAuthorizationHeader',
value: init.headers['Authorization'] value: init.headers['Authorization']
}); });
} }
}
//To prevent pause/resume loop for mid-rolls. //To prevent pause/resume loop for mid-rolls.
if (url.includes('gql') && init && typeof init.body === 'string' && init.body.includes('PlaybackAccessToken') && init.body.includes('picture-by-picture')) { if (url.includes('gql') && init && typeof init.body === 'string' && init.body.includes('PlaybackAccessToken') && init.body.includes('picture-by-picture')) {
init.body = ''; init.body = '';

View File

@ -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 5.8.4 // @version 5.8.5
// @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
@ -322,6 +322,7 @@
StreamInfos[channelName] = streamInfo = {}; StreamInfos[channelName] = streamInfo = {};
} }
streamInfo.ChannelName = channelName; streamInfo.ChannelName = channelName;
streamInfo.RequestedAds = new Set();
streamInfo.Urls = [];// xxx.m3u8 -> { Resolution: "284x160", FrameRate: 30.0 } streamInfo.Urls = [];// xxx.m3u8 -> { Resolution: "284x160", FrameRate: 30.0 }
streamInfo.EncodingsM3U8Cache = []; streamInfo.EncodingsM3U8Cache = [];
streamInfo.EncodingsM3U8 = encodingsM3u8; streamInfo.EncodingsM3U8 = encodingsM3u8;
@ -482,6 +483,21 @@
var isMidroll = textStr.includes('"MIDROLL"') || textStr.includes('"midroll"'); var isMidroll = textStr.includes('"MIDROLL"') || textStr.includes('"midroll"');
//Reduces ad frequency. TODO: Reduce the number of requests. This is really spamming Twitch with requests. //Reduces ad frequency. TODO: Reduce the number of requests. This is really spamming Twitch with requests.
if (!isMidroll) { if (!isMidroll) {
if (playerType === PlayerType2) {
var lines = textStr.replace('\r', '').split('\n');
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
if (line.startsWith('#EXTINF') && lines.length > i + 1) {
if (!line.includes(',live') && !streamInfo.RequestedAds.has(lines[i + 1])) {
// Only request one .ts file per .m3u8 request to avoid making too many requests
//console.log('Fetch ad .ts file');
streamInfo.RequestedAds.add(lines[i + 1]);
fetch(lines[i + 1]).then((response)=>{response.blob()});
break;
}
}
}
}
try { try {
//tryNotifyTwitch(textStr); //tryNotifyTwitch(textStr);
} catch (err) {} } catch (err) {}
@ -669,7 +685,7 @@
} }
function gqlRequest(body, realFetch) { function gqlRequest(body, realFetch) {
if (ClientIntegrityHeader == null) { if (ClientIntegrityHeader == null) {
console.warn('ClientIntegrityHeader is null'); //console.warn('ClientIntegrityHeader is null');
//throw 'ClientIntegrityHeader is null'; //throw 'ClientIntegrityHeader is null';
} }
var fetchFunc = realFetch ? realFetch : fetch; var fetchFunc = realFetch ? realFetch : fetch;
@ -867,17 +883,21 @@
} }
//Client integrity header //Client integrity header
ClientIntegrityHeader = init.headers['Client-Integrity']; ClientIntegrityHeader = init.headers['Client-Integrity'];
if (ClientIntegrityHeader && twitchMainWorker) {
twitchMainWorker.postMessage({ twitchMainWorker.postMessage({
key: 'UpdateClientIntegrityHeader', key: 'UpdateClientIntegrityHeader',
value: init.headers['Client-Integrity'] value: init.headers['Client-Integrity']
}); });
}
//Authorization header //Authorization header
AuthorizationHeader = init.headers['Authorization']; AuthorizationHeader = init.headers['Authorization'];
if (AuthorizationHeader && twitchMainWorker) {
twitchMainWorker.postMessage({ twitchMainWorker.postMessage({
key: 'UpdateAuthorizationHeader', key: 'UpdateAuthorizationHeader',
value: init.headers['Authorization'] value: init.headers['Authorization']
}); });
} }
}
//To prevent pause/resume loop for mid-rolls. //To prevent pause/resume loop for mid-rolls.
if (url.includes('gql') && init && typeof init.body === 'string' && init.body.includes('PlaybackAccessToken') && init.body.includes('picture-by-picture')) { if (url.includes('gql') && init && typeof init.body === 'string' && init.body.includes('PlaybackAccessToken') && init.body.includes('picture-by-picture')) {
init.body = ''; init.body = '';

View File

@ -152,11 +152,27 @@ twitch-videoad.js text/javascript
var streamM3u8Response = await realFetch(streamM3u8Url); var streamM3u8Response = await realFetch(streamM3u8Url);
if (streamM3u8Response.status == 200) { if (streamM3u8Response.status == 200) {
var streamM3u8 = await streamM3u8Response.text(); var streamM3u8 = await streamM3u8Response.text();
if (streamM3u8 != null && !streamM3u8.includes(AD_SIGNIFIER)) { if (streamM3u8 != null) {
if (!streamM3u8.includes(AD_SIGNIFIER)) {
console.log('No more ads on main stream. Triggering player reload to go back to main stream...'); console.log('No more ads on main stream. Triggering player reload to go back to main stream...');
streamInfo.UseBackupStream = false; streamInfo.UseBackupStream = false;
postMessage({key:'UboHideAdBanner'}); postMessage({key:'UboHideAdBanner'});
postMessage({key:'UboReloadPlayer'}); postMessage({key:'UboReloadPlayer'});
} else if (!streamM3u8.includes('"MIDROLL"') && !streamM3u8.includes('"midroll"')) {
var lines = streamM3u8.replace('\r', '').split('\n');
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
if (line.startsWith('#EXTINF') && lines.length > i + 1) {
if (!line.includes(LIVE_SIGNIFIER) && !streamInfo.RequestedAds.has(lines[i + 1])) {
// Only request one .ts file per .m3u8 request to avoid making too many requests
//console.log('Fetch ad .ts file');
streamInfo.RequestedAds.add(lines[i + 1]);
fetch(lines[i + 1]).then((response)=>{response.blob()});
break;
}
}
}
}
} }
} }
} }
@ -211,6 +227,7 @@ twitch-videoad.js text/javascript
var useBackupStream = false; var useBackupStream = false;
if (streamInfo == null || streamInfo.Encodings == null || streamInfo.BackupEncodings == null) { if (streamInfo == null || streamInfo.Encodings == null || streamInfo.BackupEncodings == null) {
StreamInfos[channelName] = streamInfo = { StreamInfos[channelName] = streamInfo = {
RequestedAds: new Set(),
Encodings: null, Encodings: null,
BackupEncodings: null, BackupEncodings: null,
IsMidroll: false, IsMidroll: false,
@ -340,7 +357,7 @@ twitch-videoad.js text/javascript
} }
function gqlRequest(body, realFetch) { function gqlRequest(body, realFetch) {
if (ClientIntegrityHeader == null) { if (ClientIntegrityHeader == null) {
console.warn('ClientIntegrityHeader is null'); //console.warn('ClientIntegrityHeader is null');
//throw 'ClientIntegrityHeader is null'; //throw 'ClientIntegrityHeader is null';
} }
var fetchFunc = realFetch ? realFetch : fetch; var fetchFunc = realFetch ? realFetch : fetch;
@ -466,13 +483,16 @@ twitch-videoad.js text/javascript
} }
if (typeof init.headers['Client-Integrity'] === 'string') { if (typeof init.headers['Client-Integrity'] === 'string') {
ClientIntegrityHeader = init.headers['Client-Integrity']; ClientIntegrityHeader = init.headers['Client-Integrity'];
if (ClientIntegrityHeader && twitchMainWorker) {
twitchMainWorker.postMessage({ twitchMainWorker.postMessage({
key: 'UpdateClientIntegrityHeader', key: 'UpdateClientIntegrityHeader',
value: init.headers['Client-Integrity'] value: init.headers['Client-Integrity']
}); });
} }
}
if (typeof init.headers['Authorization'] === 'string') { if (typeof init.headers['Authorization'] === 'string') {
AuthorizationHeader = init.headers['Authorization']; AuthorizationHeader = init.headers['Authorization'];
if (AuthorizationHeader && twitchMainWorker) {
twitchMainWorker.postMessage({ twitchMainWorker.postMessage({
key: 'UpdateAuthorizationHeader', key: 'UpdateAuthorizationHeader',
value: init.headers['Authorization'] value: init.headers['Authorization']
@ -481,6 +501,7 @@ twitch-videoad.js text/javascript
} }
} }
} }
}
return realFetch.apply(this, arguments); return realFetch.apply(this, arguments);
}; };
} }

View File

@ -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.21 // @version 1.22
// @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)
@ -163,11 +163,27 @@
var streamM3u8Response = await realFetch(streamM3u8Url); var streamM3u8Response = await realFetch(streamM3u8Url);
if (streamM3u8Response.status == 200) { if (streamM3u8Response.status == 200) {
var streamM3u8 = await streamM3u8Response.text(); var streamM3u8 = await streamM3u8Response.text();
if (streamM3u8 != null && !streamM3u8.includes(AD_SIGNIFIER)) { if (streamM3u8 != null) {
if (!streamM3u8.includes(AD_SIGNIFIER)) {
console.log('No more ads on main stream. Triggering player reload to go back to main stream...'); console.log('No more ads on main stream. Triggering player reload to go back to main stream...');
streamInfo.UseBackupStream = false; streamInfo.UseBackupStream = false;
postMessage({key:'UboHideAdBanner'}); postMessage({key:'UboHideAdBanner'});
postMessage({key:'UboReloadPlayer'}); postMessage({key:'UboReloadPlayer'});
} else if (!streamM3u8.includes('"MIDROLL"') && !streamM3u8.includes('"midroll"')) {
var lines = streamM3u8.replace('\r', '').split('\n');
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
if (line.startsWith('#EXTINF') && lines.length > i + 1) {
if (!line.includes(LIVE_SIGNIFIER) && !streamInfo.RequestedAds.has(lines[i + 1])) {
// Only request one .ts file per .m3u8 request to avoid making too many requests
//console.log('Fetch ad .ts file');
streamInfo.RequestedAds.add(lines[i + 1]);
fetch(lines[i + 1]).then((response)=>{response.blob()});
break;
}
}
}
}
} }
} }
} }
@ -222,6 +238,7 @@
var useBackupStream = false; var useBackupStream = false;
if (streamInfo == null || streamInfo.Encodings == null || streamInfo.BackupEncodings == null) { if (streamInfo == null || streamInfo.Encodings == null || streamInfo.BackupEncodings == null) {
StreamInfos[channelName] = streamInfo = { StreamInfos[channelName] = streamInfo = {
RequestedAds: new Set(),
Encodings: null, Encodings: null,
BackupEncodings: null, BackupEncodings: null,
IsMidroll: false, IsMidroll: false,
@ -351,7 +368,7 @@
} }
function gqlRequest(body, realFetch) { function gqlRequest(body, realFetch) {
if (ClientIntegrityHeader == null) { if (ClientIntegrityHeader == null) {
console.warn('ClientIntegrityHeader is null'); //console.warn('ClientIntegrityHeader is null');
//throw 'ClientIntegrityHeader is null'; //throw 'ClientIntegrityHeader is null';
} }
var fetchFunc = realFetch ? realFetch : fetch; var fetchFunc = realFetch ? realFetch : fetch;
@ -477,13 +494,16 @@
} }
if (typeof init.headers['Client-Integrity'] === 'string') { if (typeof init.headers['Client-Integrity'] === 'string') {
ClientIntegrityHeader = init.headers['Client-Integrity']; ClientIntegrityHeader = init.headers['Client-Integrity'];
if (ClientIntegrityHeader && twitchMainWorker) {
twitchMainWorker.postMessage({ twitchMainWorker.postMessage({
key: 'UpdateClientIntegrityHeader', key: 'UpdateClientIntegrityHeader',
value: init.headers['Client-Integrity'] value: init.headers['Client-Integrity']
}); });
} }
}
if (typeof init.headers['Authorization'] === 'string') { if (typeof init.headers['Authorization'] === 'string') {
AuthorizationHeader = init.headers['Authorization']; AuthorizationHeader = init.headers['Authorization'];
if (AuthorizationHeader && twitchMainWorker) {
twitchMainWorker.postMessage({ twitchMainWorker.postMessage({
key: 'UpdateAuthorizationHeader', key: 'UpdateAuthorizationHeader',
value: init.headers['Authorization'] value: init.headers['Authorization']
@ -492,6 +512,7 @@
} }
} }
} }
}
return realFetch.apply(this, arguments); return realFetch.apply(this, arguments);
}; };
} }