您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Optimize CPU and GPU usage while watching YouTube videos
// ==UserScript== // @name YouTube CPU-Tamer Upgrade // @version 0.3 // @description Optimize CPU and GPU usage while watching YouTube videos // @author AstralRift // @namespace https://greasyfork.org/users/1300060 // @match *://*.youtube.com/* // @match *://*.youtube-nocookie.com/embed/* // @match *://music.youtube.com/* // @exclude *://*.youtube.com/*/*.{txt,png,jpg,jpeg,gif,xml,svg,manifest,log,ini} // @run-at document-start // @grant none // @license MIT // ==/UserScript== (function () { 'use strict'; const win = this instanceof Window ? this : window; const scriptKey = 'YTB_CPUTamer_AstralRift'; if (win[scriptKey]) throw new Error('Duplicated Userscript Calling'); win[scriptKey] = true; const PromiseConstructor = function (executor) { return new Promise(executor); }; const ExternalPromise = (function () { let resolve_, reject_; const handler = function (resolve, reject) { resolve_ = resolve; reject_ = reject; }; const PromiseExternal = function (cb) { cb = cb || handler; const promise = new PromiseConstructor(cb); if (cb === handler) { promise.resolve = resolve_; promise.reject = reject_; } return promise; }; return PromiseExternal; })(); const checkGPUAcceleration = (function () { try { const canvas = document.createElement('canvas'); return !!(canvas.getContext('webgl') || canvas.getContext('experimental-webgl')); } catch (e) { return false; } })(); if (!checkGPUAcceleration) { throw new Error('Your browser does not support GPU Acceleration. YouTube CPU-Tamer is skipped.'); } const getTimeUpdate = (function () { window.lastTimeUpdate = 1; document.addEventListener('timeupdate', function () { window.lastTimeUpdate = Date.now(); }, true); let topLastTimeUpdate = -1; try { topLastTimeUpdate = top.lastTimeUpdate; } catch (e) { } return topLastTimeUpdate >= 1 ? function () { return top.lastTimeUpdate; } : function () { return window.lastTimeUpdate; }; })(); const initializeContext = function (win) { return new PromiseConstructor(function (resolve) { const waitForFrame = requestAnimationFrame; let maxRetries = 16; const frameId = 'vanillajs-iframe-v1'; let frame = document.getElementById(frameId); let removeFrame = null; if (!frame) { frame = document.createElement('iframe'); frame.id = frameId; const blobURL = typeof webkitCancelAnimationFrame === 'function' && typeof kagi === 'undefined' ? (frame.src = URL.createObjectURL(new Blob([], { type: 'text/html' }))) : null; frame.sandbox = 'allow-same-origin'; let noscriptElement = document.createElement('noscript'); noscriptElement.appendChild(frame); (function waitForDocument() { if (!document.documentElement && maxRetries-- > 0) { return new PromiseConstructor(waitForFrame).then(waitForDocument); } const root = document.documentElement; root.appendChild(noscriptElement); if (blobURL) PromiseConstructor.resolve().then(function () { URL.revokeObjectURL(blobURL); }); removeFrame = function (setTimeout) { const removeFrameWhenReady = function (e) { if (e) win.removeEventListener("DOMContentLoaded", removeFrameWhenReady, false); e = noscriptElement; noscriptElement = win = removeFrame = 0; if (setTimeout) { setTimeout(function () { e.remove(); }, 200); } else { e.remove(); } }; if (!setTimeout || document.readyState !== 'loading') { removeFrameWhenReady(); } else { win.addEventListener("DOMContentLoaded", removeFrameWhenReady, false); } }; })(); } (function waitForFrameContext() { if (!frame.contentWindow && maxRetries-- > 0) { return new PromiseConstructor(waitForFrame).then(waitForFrameContext); } const frameContext = frame.contentWindow; if (!frameContext) throw new Error('window is not found.'); try { const { requestAnimationFrame, setInterval, setTimeout, clearInterval, clearTimeout } = frameContext; const boundFunctions = { requestAnimationFrame, setInterval, setTimeout, clearInterval, clearTimeout }; for (let key in boundFunctions) boundFunctions[key] = boundFunctions[key].bind(win); if (removeFrame) PromiseConstructor.resolve(boundFunctions.setTimeout).then(removeFrame); resolve(boundFunctions); } catch (e) { if (removeFrame) removeFrame(); resolve(null); } })(); }); }; initializeContext(win).then(function (context) { if (!context) return null; const { requestAnimationFrame, setTimeout, setInterval, clearTimeout, clearInterval } = context; let animationFrameInterrupter = null; const createRAFHelper = function () { const animationElement = document.createElement('a-f'); if (!('onanimationiteration' in animationElement)) { return function (resolve) { animationFrameInterrupter = resolve; requestAnimationFrame(resolve); }; } animationElement.id = 'a-f'; let animationQueue = null; animationElement.onanimationiteration = function () { if (animationQueue !== null) { animationQueue(); animationQueue = null; } }; if (!document.getElementById('afscript')) { const style = document.createElement('style'); style.id = 'afscript'; style.textContent = ` @keyFrames aF1 { 0% { order: 0; } 100% { order: 1; } } #a-f[id] { visibility: collapse !important; position: fixed !important; display: block !important; top: -100px !important; left: -100px !important; margin: 0 !important; padding: 0 !important; outline: 0 !important; border: 0 !important; z-index: -1 !important; width: 0px !important; height: 0px !important; contain: strict !important; pointer-events: none !important; animation: 1ms steps(2, jump-none) 0ms infinite alternate forwards running aF1 !important; } `; (document.head || document.documentElement).appendChild(style); } document.documentElement.insertBefore(animationElement, document.documentElement.firstChild); return function (resolve) { animationQueue = resolve; animationFrameInterrupter = resolve; }; }; const rafHelper = createRAFHelper(); (function () { let afPromisePrimary, afPromiseSecondary; afPromisePrimary = afPromiseSecondary = { resolved: true }; let afIndex = 0; const resolveRAF = function (rafPromise) { return new PromiseConstructor(function (resolve) { rafHelper(resolve); }).then(function () { rafPromise.resolved = true; const time = ++afIndex; if (time > 9e9) afIndex = 9; rafPromise.resolve(time); return time; }); }; const executeRAF = function () { return new PromiseConstructor(function (resolve) { const pendingPrimary = !afPromisePrimary.resolved ? afPromisePrimary : null; const pendingSecondary = !afPromiseSecondary.resolved ? afPromiseSecondary : null; let time = 0; if (pendingPrimary && pendingSecondary) { resolve(PromiseConstructor.all([pendingPrimary, pendingSecondary]).then(function (times) { const t1 = times[0]; const t2 = times[1]; time = t1 > t2 && t1 - t2 < 8e9 ? t1 : t2; return time; })); } else { const newPrimary = !pendingPrimary ? (afPromisePrimary = new ExternalPromise()) : null; const newSecondary = !pendingSecondary ? (afPromiseSecondary = new ExternalPromise()) : null; const executeSecondary = function () { if (newPrimary) { resolveRAF(newPrimary).then(function (t) { time = t; if (newSecondary) { resolveRAF(newSecondary).then(function (t2) { time = t2; resolve(time); }); } else { resolve(time); } }); } else if (newSecondary) { resolveRAF(newSecondary).then(function (t) { time = t; resolve(time); }); } else { resolve(time); } }; if (pendingSecondary) { pendingSecondary.then(function () { executeSecondary(); }); } else if (pendingPrimary) { pendingPrimary.then(function () { executeSecondary(); }); } else { executeSecondary(); } } }); }; const executingTasks = new Set(); const wrapFunction = function (handler, store) { return function () { const currentTime = Date.now(); if (currentTime - getTimeUpdate() < 800 && currentTime - store.lastTime < 800) { const id = store.id; executingTasks.add(id); executeRAF().then(function (time) { const isNotRemoved = executingTasks.delete(id); if (!isNotRemoved || time === store.lastExecution) return; store.lastExecution = time; store.lastTime = currentTime; handler(); }); } else { store.lastTime = currentTime; handler(); } }; }; const createFunctionWrapper = function (originalFunction) { return function (func, ms) { if (ms === undefined) ms = 0; if (typeof func === 'function') { const store = { lastTime: Date.now() }; const wrappedFunc = wrapFunction(func, store); store.id = originalFunction(wrappedFunc, ms); return store.id; } else { return originalFunction(func, ms); } }; }; win.setTimeout = createFunctionWrapper(setTimeout); win.setInterval = createFunctionWrapper(setInterval); const clearFunctionWrapper = function (originalFunction) { return function (id) { if (id) executingTasks.delete(id) || originalFunction(id); }; }; win.clearTimeout = clearFunctionWrapper(clearTimeout); win.clearInterval = clearFunctionWrapper(clearInterval); try { win.setTimeout.toString = setTimeout.toString.bind(setTimeout); win.setInterval.toString = setInterval.toString.bind(setInterval); win.clearTimeout.toString = clearTimeout.toString.bind(clearTimeout); win.clearInterval.toString = clearInterval.toString.bind(clearInterval); } catch (e) { console.warn(e); } })(); let intervalInterrupter = null; setInterval(function () { if (intervalInterrupter === animationFrameInterrupter) { if (intervalInterrupter !== null) { animationFrameInterrupter(); intervalInterrupter = null; } } else { intervalInterrupter = animationFrameInterrupter; } }, 125); }); })();