Fix vaft streams starting in a paused state when opened in a new tab #492
This commit is contained in:
@@ -2,7 +2,7 @@ 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; }
|
||||||
'use strict';
|
'use strict';
|
||||||
const ourTwitchAdSolutionsVersion = 23;// Used to prevent conflicts with outdated versions of the scripts
|
const ourTwitchAdSolutionsVersion = 24;// Used to prevent conflicts with outdated versions of the scripts
|
||||||
if (typeof window.twitchAdSolutionsVersion !== 'undefined' && window.twitchAdSolutionsVersion >= ourTwitchAdSolutionsVersion) {
|
if (typeof window.twitchAdSolutionsVersion !== 'undefined' && window.twitchAdSolutionsVersion >= ourTwitchAdSolutionsVersion) {
|
||||||
console.log("skipping vaft as there's another script active. ourVersion:" + ourTwitchAdSolutionsVersion + " activeVersion:" + window.twitchAdSolutionsVersion);
|
console.log("skipping vaft as there's another script active. ourVersion:" + ourTwitchAdSolutionsVersion + " activeVersion:" + window.twitchAdSolutionsVersion);
|
||||||
window.twitchAdSolutionsVersion = ourTwitchAdSolutionsVersion;
|
window.twitchAdSolutionsVersion = ourTwitchAdSolutionsVersion;
|
||||||
@@ -23,7 +23,7 @@ twitch-videoad.js text/javascript
|
|||||||
scope.SkipPlayerReloadOnHevc = false;// If true this will skip player reload on streams which have 2k/4k quality (if you enable this and you use the 2k/4k quality setting you'll get error #4000 / #3000 / spinning wheel on chrome based browsers)
|
scope.SkipPlayerReloadOnHevc = false;// If true this will skip player reload on streams which have 2k/4k quality (if you enable this and you use the 2k/4k quality setting you'll get error #4000 / #3000 / spinning wheel on chrome based browsers)
|
||||||
scope.AlwaysReloadPlayerOnAd = false;// Always pause/play when entering/leaving ads
|
scope.AlwaysReloadPlayerOnAd = false;// Always pause/play when entering/leaving ads
|
||||||
scope.ReloadPlayerAfterAd = true;// After the ad finishes do a player reload instead of pause/play
|
scope.ReloadPlayerAfterAd = true;// After the ad finishes do a player reload instead of pause/play
|
||||||
scope.PlayerReloadMinimalRequestsTime = 1600;
|
scope.PlayerReloadMinimalRequestsTime = 1500;
|
||||||
scope.PlayerReloadMinimalRequestsPlayerIndex = 2;//autoplay
|
scope.PlayerReloadMinimalRequestsPlayerIndex = 2;//autoplay
|
||||||
scope.HasTriggeredPlayerReload = false;
|
scope.HasTriggeredPlayerReload = false;
|
||||||
scope.StreamInfos = [];
|
scope.StreamInfos = [];
|
||||||
@@ -39,7 +39,7 @@ twitch-videoad.js text/javascript
|
|||||||
scope.PlayerBufferingSameStateCount = 3;// How many times of seeing the same player state until we trigger pause/play (it will only trigger it one time until the player state changes again)
|
scope.PlayerBufferingSameStateCount = 3;// How many times of seeing the same player state until we trigger pause/play (it will only trigger it one time until the player state changes again)
|
||||||
scope.PlayerBufferingDangerZone = 1;// The buffering time left (in seconds) when we should ignore the players playback position in the player state check
|
scope.PlayerBufferingDangerZone = 1;// The buffering time left (in seconds) when we should ignore the players playback position in the player state check
|
||||||
scope.PlayerBufferingDoPlayerReload = false;// If true this will do a player reload instead of pause/play (player reloading is better at fixing the playback issues but it takes slightly longer)
|
scope.PlayerBufferingDoPlayerReload = false;// If true this will do a player reload instead of pause/play (player reloading is better at fixing the playback issues but it takes slightly longer)
|
||||||
scope.PlayerBufferingMinRepeatDelay = 12000;// Minimum delay (in milliseconds) between each pause/play (this is to avoid over pressing pause/play when there are genuine buffering problems)
|
scope.PlayerBufferingMinRepeatDelay = 8000;// Minimum delay (in milliseconds) between each pause/play (this is to avoid over pressing pause/play when there are genuine buffering problems)
|
||||||
scope.PlayerBufferingPrerollCheckEnabled = false;// Enable this if you're getting an immediate pause/play/reload as you open a stream (which is causing the stream to take longer to load). One problem with this being true is that it can cause the player to get stuck in some instances requiring the user to press pause/play
|
scope.PlayerBufferingPrerollCheckEnabled = false;// Enable this if you're getting an immediate pause/play/reload as you open a stream (which is causing the stream to take longer to load). One problem with this being true is that it can cause the player to get stuck in some instances requiring the user to press pause/play
|
||||||
scope.PlayerBufferingPrerollCheckOffset = 5;// How far the stream need to move before doing the buffering mitigation (depends on PlayerBufferingPrerollCheckEnabled being true)
|
scope.PlayerBufferingPrerollCheckOffset = 5;// How far the stream need to move before doing the buffering mitigation (depends on PlayerBufferingPrerollCheckEnabled being true)
|
||||||
scope.V2API = false;
|
scope.V2API = false;
|
||||||
@@ -681,6 +681,8 @@ twitch-videoad.js text/javascript
|
|||||||
}
|
}
|
||||||
let playerForMonitoringBuffering = null;
|
let playerForMonitoringBuffering = null;
|
||||||
const playerBufferState = {
|
const playerBufferState = {
|
||||||
|
channelName: null,
|
||||||
|
hasStreamStarted: false,
|
||||||
position: 0,
|
position: 0,
|
||||||
bufferedPosition: 0,
|
bufferedPosition: 0,
|
||||||
bufferDuration: 0,
|
bufferDuration: 0,
|
||||||
@@ -696,13 +698,30 @@ twitch-videoad.js text/javascript
|
|||||||
if (!player.core) {
|
if (!player.core) {
|
||||||
playerForMonitoringBuffering = null;
|
playerForMonitoringBuffering = null;
|
||||||
} else if (state.props?.content?.type === 'live' && !player.isPaused() && !player.getHTMLVideoElement()?.ended && playerBufferState.lastFixTime <= Date.now() - PlayerBufferingMinRepeatDelay && !isActivelyStrippingAds) {
|
} else if (state.props?.content?.type === 'live' && !player.isPaused() && !player.getHTMLVideoElement()?.ended && playerBufferState.lastFixTime <= Date.now() - PlayerBufferingMinRepeatDelay && !isActivelyStrippingAds) {
|
||||||
|
const m3u8Url = player.core?.state?.path;
|
||||||
|
if (m3u8Url) {
|
||||||
|
const fileName = new URL(m3u8Url).pathname.split('/').pop();
|
||||||
|
if (fileName?.endsWith('.m3u8')) {
|
||||||
|
const channelName = fileName.slice(0, -5);
|
||||||
|
if (playerBufferState.channelName != channelName) {
|
||||||
|
playerBufferState.channelName = channelName;
|
||||||
|
playerBufferState.hasStreamStarted = false;
|
||||||
|
playerBufferState.numSame = 0;
|
||||||
|
//console.log('Channel changed to ' + channelName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (player.getState() === 'Playing') {
|
||||||
|
playerBufferState.hasStreamStarted = true;
|
||||||
|
}
|
||||||
const position = player.core?.state?.position;
|
const position = player.core?.state?.position;
|
||||||
const bufferedPosition = player.core?.state?.bufferedPosition;
|
const bufferedPosition = player.core?.state?.bufferedPosition;
|
||||||
const bufferDuration = player.getBufferDuration();
|
const bufferDuration = player.getBufferDuration();
|
||||||
if (position !== undefined && bufferedPosition !== undefined) {
|
if (position !== undefined && bufferedPosition !== undefined) {
|
||||||
//console.log('position:' + position + ' bufferDuration:' + bufferDuration + ' bufferPosition:' + bufferedPosition);
|
//console.log('position:' + position + ' bufferDuration:' + bufferDuration + ' bufferPosition:' + bufferedPosition + ' state: ' + player.core?.state?.state + ' started: ' + playerBufferState.hasStreamStarted);
|
||||||
// NOTE: This could be improved. It currently lets the player fully eat the full buffer before it triggers pause/play
|
// NOTE: This could be improved. It currently lets the player fully eat the full buffer before it triggers pause/play
|
||||||
if ((!PlayerBufferingPrerollCheckEnabled || position > PlayerBufferingPrerollCheckOffset) &&
|
if (playerBufferState.hasStreamStarted &&
|
||||||
|
(!PlayerBufferingPrerollCheckEnabled || position > PlayerBufferingPrerollCheckOffset) &&
|
||||||
(playerBufferState.position == position || bufferDuration < PlayerBufferingDangerZone) &&
|
(playerBufferState.position == position || bufferDuration < PlayerBufferingDangerZone) &&
|
||||||
playerBufferState.bufferedPosition == bufferedPosition &&
|
playerBufferState.bufferedPosition == bufferedPosition &&
|
||||||
playerBufferState.bufferDuration >= bufferDuration &&
|
playerBufferState.bufferDuration >= bufferDuration &&
|
||||||
@@ -990,12 +1009,17 @@ twitch-videoad.js text/javascript
|
|||||||
};
|
};
|
||||||
let wasVideoPlaying = true;
|
let wasVideoPlaying = true;
|
||||||
const visibilityChange = e => {
|
const visibilityChange = e => {
|
||||||
if (typeof chrome !== 'undefined') {
|
const isChrome = typeof chrome !== 'undefined';
|
||||||
const videos = document.getElementsByTagName('video');
|
const videos = document.getElementsByTagName('video');
|
||||||
if (videos.length > 0) {
|
if (videos.length > 0) {
|
||||||
if (hidden.apply(document) === true || (webkitHidden && webkitHidden.apply(document) === true)) {
|
if (hidden.apply(document) === true || (webkitHidden && webkitHidden.apply(document) === true)) {
|
||||||
wasVideoPlaying = !videos[0].paused && !videos[0].ended;
|
wasVideoPlaying = !videos[0].paused && !videos[0].ended;
|
||||||
} else if (wasVideoPlaying && !videos[0].ended && videos[0].paused && videos[0].muted) {
|
} else {
|
||||||
|
if (!playerBufferState.hasStreamStarted) {
|
||||||
|
//console.log('Tab focused. Stream should be active');
|
||||||
|
playerBufferState.hasStreamStarted = true;
|
||||||
|
}
|
||||||
|
if (isChrome && wasVideoPlaying && !videos[0].ended && videos[0].paused && videos[0].muted) {
|
||||||
videos[0].play();
|
videos[0].play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+32
-8
@@ -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 36.0.0
|
// @version 37.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,7 +13,7 @@
|
|||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
(function() {
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
const ourTwitchAdSolutionsVersion = 23;// Used to prevent conflicts with outdated versions of the scripts
|
const ourTwitchAdSolutionsVersion = 24;// Used to prevent conflicts with outdated versions of the scripts
|
||||||
if (typeof window.twitchAdSolutionsVersion !== 'undefined' && window.twitchAdSolutionsVersion >= ourTwitchAdSolutionsVersion) {
|
if (typeof window.twitchAdSolutionsVersion !== 'undefined' && window.twitchAdSolutionsVersion >= ourTwitchAdSolutionsVersion) {
|
||||||
console.log("skipping vaft as there's another script active. ourVersion:" + ourTwitchAdSolutionsVersion + " activeVersion:" + window.twitchAdSolutionsVersion);
|
console.log("skipping vaft as there's another script active. ourVersion:" + ourTwitchAdSolutionsVersion + " activeVersion:" + window.twitchAdSolutionsVersion);
|
||||||
window.twitchAdSolutionsVersion = ourTwitchAdSolutionsVersion;
|
window.twitchAdSolutionsVersion = ourTwitchAdSolutionsVersion;
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
scope.SkipPlayerReloadOnHevc = false;// If true this will skip player reload on streams which have 2k/4k quality (if you enable this and you use the 2k/4k quality setting you'll get error #4000 / #3000 / spinning wheel on chrome based browsers)
|
scope.SkipPlayerReloadOnHevc = false;// If true this will skip player reload on streams which have 2k/4k quality (if you enable this and you use the 2k/4k quality setting you'll get error #4000 / #3000 / spinning wheel on chrome based browsers)
|
||||||
scope.AlwaysReloadPlayerOnAd = false;// Always pause/play when entering/leaving ads
|
scope.AlwaysReloadPlayerOnAd = false;// Always pause/play when entering/leaving ads
|
||||||
scope.ReloadPlayerAfterAd = true;// After the ad finishes do a player reload instead of pause/play
|
scope.ReloadPlayerAfterAd = true;// After the ad finishes do a player reload instead of pause/play
|
||||||
scope.PlayerReloadMinimalRequestsTime = 1600;
|
scope.PlayerReloadMinimalRequestsTime = 1500;
|
||||||
scope.PlayerReloadMinimalRequestsPlayerIndex = 2;//autoplay
|
scope.PlayerReloadMinimalRequestsPlayerIndex = 2;//autoplay
|
||||||
scope.HasTriggeredPlayerReload = false;
|
scope.HasTriggeredPlayerReload = false;
|
||||||
scope.StreamInfos = [];
|
scope.StreamInfos = [];
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
scope.PlayerBufferingSameStateCount = 3;// How many times of seeing the same player state until we trigger pause/play (it will only trigger it one time until the player state changes again)
|
scope.PlayerBufferingSameStateCount = 3;// How many times of seeing the same player state until we trigger pause/play (it will only trigger it one time until the player state changes again)
|
||||||
scope.PlayerBufferingDangerZone = 1;// The buffering time left (in seconds) when we should ignore the players playback position in the player state check
|
scope.PlayerBufferingDangerZone = 1;// The buffering time left (in seconds) when we should ignore the players playback position in the player state check
|
||||||
scope.PlayerBufferingDoPlayerReload = false;// If true this will do a player reload instead of pause/play (player reloading is better at fixing the playback issues but it takes slightly longer)
|
scope.PlayerBufferingDoPlayerReload = false;// If true this will do a player reload instead of pause/play (player reloading is better at fixing the playback issues but it takes slightly longer)
|
||||||
scope.PlayerBufferingMinRepeatDelay = 12000;// Minimum delay (in milliseconds) between each pause/play (this is to avoid over pressing pause/play when there are genuine buffering problems)
|
scope.PlayerBufferingMinRepeatDelay = 8000;// Minimum delay (in milliseconds) between each pause/play (this is to avoid over pressing pause/play when there are genuine buffering problems)
|
||||||
scope.PlayerBufferingPrerollCheckEnabled = false;// Enable this if you're getting an immediate pause/play/reload as you open a stream (which is causing the stream to take longer to load). One problem with this being true is that it can cause the player to get stuck in some instances requiring the user to press pause/play
|
scope.PlayerBufferingPrerollCheckEnabled = false;// Enable this if you're getting an immediate pause/play/reload as you open a stream (which is causing the stream to take longer to load). One problem with this being true is that it can cause the player to get stuck in some instances requiring the user to press pause/play
|
||||||
scope.PlayerBufferingPrerollCheckOffset = 5;// How far the stream need to move before doing the buffering mitigation (depends on PlayerBufferingPrerollCheckEnabled being true)
|
scope.PlayerBufferingPrerollCheckOffset = 5;// How far the stream need to move before doing the buffering mitigation (depends on PlayerBufferingPrerollCheckEnabled being true)
|
||||||
scope.V2API = false;
|
scope.V2API = false;
|
||||||
@@ -692,6 +692,8 @@
|
|||||||
}
|
}
|
||||||
let playerForMonitoringBuffering = null;
|
let playerForMonitoringBuffering = null;
|
||||||
const playerBufferState = {
|
const playerBufferState = {
|
||||||
|
channelName: null,
|
||||||
|
hasStreamStarted: false,
|
||||||
position: 0,
|
position: 0,
|
||||||
bufferedPosition: 0,
|
bufferedPosition: 0,
|
||||||
bufferDuration: 0,
|
bufferDuration: 0,
|
||||||
@@ -707,13 +709,30 @@
|
|||||||
if (!player.core) {
|
if (!player.core) {
|
||||||
playerForMonitoringBuffering = null;
|
playerForMonitoringBuffering = null;
|
||||||
} else if (state.props?.content?.type === 'live' && !player.isPaused() && !player.getHTMLVideoElement()?.ended && playerBufferState.lastFixTime <= Date.now() - PlayerBufferingMinRepeatDelay && !isActivelyStrippingAds) {
|
} else if (state.props?.content?.type === 'live' && !player.isPaused() && !player.getHTMLVideoElement()?.ended && playerBufferState.lastFixTime <= Date.now() - PlayerBufferingMinRepeatDelay && !isActivelyStrippingAds) {
|
||||||
|
const m3u8Url = player.core?.state?.path;
|
||||||
|
if (m3u8Url) {
|
||||||
|
const fileName = new URL(m3u8Url).pathname.split('/').pop();
|
||||||
|
if (fileName?.endsWith('.m3u8')) {
|
||||||
|
const channelName = fileName.slice(0, -5);
|
||||||
|
if (playerBufferState.channelName != channelName) {
|
||||||
|
playerBufferState.channelName = channelName;
|
||||||
|
playerBufferState.hasStreamStarted = false;
|
||||||
|
playerBufferState.numSame = 0;
|
||||||
|
//console.log('Channel changed to ' + channelName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (player.getState() === 'Playing') {
|
||||||
|
playerBufferState.hasStreamStarted = true;
|
||||||
|
}
|
||||||
const position = player.core?.state?.position;
|
const position = player.core?.state?.position;
|
||||||
const bufferedPosition = player.core?.state?.bufferedPosition;
|
const bufferedPosition = player.core?.state?.bufferedPosition;
|
||||||
const bufferDuration = player.getBufferDuration();
|
const bufferDuration = player.getBufferDuration();
|
||||||
if (position !== undefined && bufferedPosition !== undefined) {
|
if (position !== undefined && bufferedPosition !== undefined) {
|
||||||
//console.log('position:' + position + ' bufferDuration:' + bufferDuration + ' bufferPosition:' + bufferedPosition);
|
//console.log('position:' + position + ' bufferDuration:' + bufferDuration + ' bufferPosition:' + bufferedPosition + ' state: ' + player.core?.state?.state + ' started: ' + playerBufferState.hasStreamStarted);
|
||||||
// NOTE: This could be improved. It currently lets the player fully eat the full buffer before it triggers pause/play
|
// NOTE: This could be improved. It currently lets the player fully eat the full buffer before it triggers pause/play
|
||||||
if ((!PlayerBufferingPrerollCheckEnabled || position > PlayerBufferingPrerollCheckOffset) &&
|
if (playerBufferState.hasStreamStarted &&
|
||||||
|
(!PlayerBufferingPrerollCheckEnabled || position > PlayerBufferingPrerollCheckOffset) &&
|
||||||
(playerBufferState.position == position || bufferDuration < PlayerBufferingDangerZone) &&
|
(playerBufferState.position == position || bufferDuration < PlayerBufferingDangerZone) &&
|
||||||
playerBufferState.bufferedPosition == bufferedPosition &&
|
playerBufferState.bufferedPosition == bufferedPosition &&
|
||||||
playerBufferState.bufferDuration >= bufferDuration &&
|
playerBufferState.bufferDuration >= bufferDuration &&
|
||||||
@@ -1001,12 +1020,17 @@
|
|||||||
};
|
};
|
||||||
let wasVideoPlaying = true;
|
let wasVideoPlaying = true;
|
||||||
const visibilityChange = e => {
|
const visibilityChange = e => {
|
||||||
if (typeof chrome !== 'undefined') {
|
const isChrome = typeof chrome !== 'undefined';
|
||||||
const videos = document.getElementsByTagName('video');
|
const videos = document.getElementsByTagName('video');
|
||||||
if (videos.length > 0) {
|
if (videos.length > 0) {
|
||||||
if (hidden.apply(document) === true || (webkitHidden && webkitHidden.apply(document) === true)) {
|
if (hidden.apply(document) === true || (webkitHidden && webkitHidden.apply(document) === true)) {
|
||||||
wasVideoPlaying = !videos[0].paused && !videos[0].ended;
|
wasVideoPlaying = !videos[0].paused && !videos[0].ended;
|
||||||
} else if (wasVideoPlaying && !videos[0].ended && videos[0].paused && videos[0].muted) {
|
} else {
|
||||||
|
if (!playerBufferState.hasStreamStarted) {
|
||||||
|
//console.log('Tab focused. Stream should be active');
|
||||||
|
playerBufferState.hasStreamStarted = true;
|
||||||
|
}
|
||||||
|
if (isChrome && wasVideoPlaying && !videos[0].ended && videos[0].paused && videos[0].muted) {
|
||||||
videos[0].play();
|
videos[0].play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user