您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Fuerza YouTube a reproducir videos a 30 FPS máximo, reduciendo el uso de CPU y mejorando el rendimiento en equipos antiguos
// ==UserScript== // @name YouTube 30 FPS Forzado // @name:en YouTube 30 FPS Forced // @namespace AkioBrian // @version 2.0.0 // @description Fuerza YouTube a reproducir videos a 30 FPS máximo, reduciendo el uso de CPU y mejorando el rendimiento en equipos antiguos // @description:en Forces YouTube to play videos at a maximum of 30 FPS, reducing CPU usage and improving performance on older devices. // @icon https://i.imgur.com/oM51Lex.png // @author SteveJobzniak, AkioBrian // @license https://www.apache.org/licenses/LICENSE-2.0 // @match *://www.youtube.com/* // @exclude *://www.youtube.com/tv* // @exclude *://www.youtube.com/embed/* // @run-at document-start // @grant none // @noframes // ==/UserScript== (function() { 'use strict'; // Configuración const CONFIG = { DEBUG: false, MAX_FPS: 30, MAX_REINTENTOS: 2, TIMEOUT_VERIFICACION: 8000 }; // Crear verificador de formatos personalizado const crearVerificadorFormatos = (verificadorOriginal, callback) => { return function(tipoVideo) { if (CONFIG.DEBUG) { console.log(`[YouTube 30FPS] Consulta: "${tipoVideo}"`); } callback?.('query', tipoVideo); if (!tipoVideo) return false; // Bloquear formatos de alta frecuencia const coincidencias = tipoVideo.match(/framerate=(\d+)/); if (coincidencias) { const fps = parseInt(coincidencias[1], 10); if (fps > CONFIG.MAX_FPS) { if (CONFIG.DEBUG) { console.log(`[YouTube 30FPS] Bloqueado: ${fps}fps`); } callback?.('block', tipoVideo); return false; } } return verificadorOriginal(tipoVideo); }; }; // Verificar si estamos en una página de video const esPaginaVideo = () => location.pathname === '/watch'; // Obtener contador de recargas de la URL const obtenerContadorRecargas = () => { if (!location.hash) return null; const coincidencias = location.hash.match(/fpsreloads=(\d+)/); return coincidencias ? parseInt(coincidencias[1], 10) : null; }; // Establecer contador y recargar página const establecerContadorYRecargar = (nuevoContador) => { let hashAntiguo = location.hash.replace(/^#/, '').replace(/&?fpsreloads=\d+/, ''); let hashNuevo = hashAntiguo ? `${hashAntiguo}&fpsreloads=${nuevoContador}` : `fpsreloads=${nuevoContador}`; location.hash = hashNuevo; location.reload(); }; // Eliminar contador de recargas de la URL const eliminarContadorRecargas = () => { if (window.history?.replaceState) { const nuevaUrl = location.href.replace(/(#?)fpsreloads=\d+&?/g, '$1').replace(/[#&]+$/, ''); if (location.href !== nuevaUrl) { window.history.replaceState({}, document.title, nuevaUrl); } } }; // Manejar reintentos de inyección const manejarReintentos = (exitoso, recargasActuales) => { if (exitoso || !esPaginaVideo()) { eliminarContadorRecargas(); if (CONFIG.DEBUG) { console.log('[YouTube 30FPS] Inyección exitosa'); } return; } const siguienteRecarga = (recargasActuales ?? 0) + 1; if (siguienteRecarga <= CONFIG.MAX_REINTENTOS) { if (CONFIG.DEBUG) { console.log(`[YouTube 30FPS] Reintento ${siguienteRecarga}/${CONFIG.MAX_REINTENTOS}`); } establecerContadorYRecargar(siguienteRecarga); } else { eliminarContadorRecargas(); mostrarMensajeError(); } }; // Mostrar mensaje de error con auto-ocultado const mostrarMensajeError = () => { const crearDivError = () => { if (!document.body || document.getElementById('youtube-30fps-error')) { return false; } const divError = document.createElement('div'); divError.id = 'youtube-30fps-error'; Object.assign(divError.style, { position: 'fixed', bottom: '20px', right: '20px', maxWidth: '350px', padding: '15px', borderRadius: '8px', fontSize: '14px', color: '#fff', backgroundColor: 'rgba(244, 67, 54, 0.95)', boxShadow: '0 4px 12px rgba(0,0,0,0.3)', zIndex: '99999', fontFamily: 'Arial, sans-serif', lineHeight: '1.4' }); divError.innerHTML = ` <div style="font-weight: bold; margin-bottom: 8px;">⚠️ YouTube 30 FPS</div> <div style="margin-bottom: 10px;">No se pudo limitar a 30 FPS en esta pestaña.</div> <div style="font-size: 12px;"> <a href="#" onclick="location.reload(); return false" style="color: #ffcdd2; text-decoration: underline;">Recargar página</a> • <a href="#" onclick="this.parentElement.parentElement.parentElement.remove(); return false" style="color: #ffcdd2; text-decoration: underline;">Cerrar</a> </div> `; document.body.appendChild(divError); // Auto-ocultar después de 10 segundos setTimeout(() => { if (divError.parentNode) { divError.style.transition = 'opacity 0.5s ease-out'; divError.style.opacity = '0'; setTimeout(() => divError.remove(), 500); } }, 10000); return true; }; if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', crearDivError); } else { crearDivError(); } }; // Verificar soporte para MediaSource if (!window.MediaSource) { console.warn('MediaSource no soportado en este navegador'); return; } const recargasActuales = obtenerContadorRecargas(); // Verificar si la inyección fue demasiado tardía const inyeccionTardia = window.ytplayer && Object.getOwnPropertyNames(window.ytplayer).length > 0; if (esPaginaVideo() && inyeccionTardia) { manejarReintentos(false, recargasActuales); return; } // Limpiar contador de recargas si la inyección parece exitosa eliminarContadorRecargas(); // Configurar verificación de éxito let contadorBloqueos = 0; const actualizarContadorBloqueos = (accion) => { if (accion === 'block') contadorBloqueos++; }; const verificarExito = () => { const exitoso = contadorBloqueos >= 1; manejarReintentos(exitoso, recargasActuales); }; // Configurar timer de verificación para páginas de video if (esPaginaVideo()) { setTimeout(verificarExito, CONFIG.TIMEOUT_VERIFICACION); } else { manejarReintentos(true, recargasActuales); } // Inyectar el bloqueador de formatos de video try { const verificadorOriginal = window.MediaSource.isTypeSupported.bind(window.MediaSource); window.MediaSource.isTypeSupported = crearVerificadorFormatos(verificadorOriginal, actualizarContadorBloqueos); if (CONFIG.DEBUG) { console.log('[YouTube 30FPS] Script inyectado correctamente'); } } catch (error) { console.error('[YouTube 30FPS] Error al inyectar:', error); } })();