// ==UserScript== // @name Twitch - Disable automatic video downscale // @namespace CommanderRoot // @copyright CommanderRoot // @license Unlicense // @version 1.2.2 // @description Disables the automatic downscaling of Twitch streams while tabbed away // @author https://twitter.com/CommanderRoot // @match https://www.twitch.tv/* // @match https://m.twitch.tv/* // @match https://player.twitch.tv/* // @grant none // @run-at document-start // @downloadURL none // ==/UserScript== "use strict"; // Try to trick the site into thinking it's never hidden Object.defineProperty(document, 'hidden', { value: false, writable: false }); Object.defineProperty(document, 'mozHidden', { value: false, writable: false }); Object.defineProperty(document, 'webkitHidden', { value: false, writable: false }); Object.defineProperty(document, 'visibilityState', { value: 'visible', writable: false }); Object.defineProperty(document, 'webkitVisibilityState', { value: 'visible', writable: false }); document.hasFocus = function () { return true; }; document.dispatchEvent(new Event('visibilitychange')); let lastVideoPlaying = null; // visibilitychange events are captured and stopped document.addEventListener('visibilitychange', function (e) { e.stopImmediatePropagation(); // Try to play the video on Chrome if (typeof chrome !== 'undefined') { playVideo(); } }, true); function setQualitySettings() { // Set the player quality to "Source" try { window.localStorage.setItem('s-qs-ts', Math.floor(Date.now())); window.localStorage.setItem('video-quality', '{"default":"chunked"}'); } catch (e) { console.log(e); } } function playVideo() { const videos = document.getElementsByTagName('video'); if (videos.length > 0) { const lastStatus = lastVideoPlaying; lastVideoPlaying = !videos[0].paused && !videos[0].ended; if (lastStatus === true && !videos[0].ended) { videos[0].play(); } } else { lastStatus = null; } } setQualitySettings(); // Add event handler for when we switch between pages // This is useful when we switch for example from a Clip // without "Source" to a livestream window.addEventListener('popstate', () => { setQualitySettings(); });