您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Lightweight speed control for YouTube with persistence
// ==UserScript== // @name YT Speed Controller // @namespace -/- // @version 1.0.1 // @description Lightweight speed control for YouTube with persistence // @author Dataraj // @match https://www.youtube.com/* // @license MIT // @grant none // ==/UserScript== (function() { 'use strict'; const STORAGE_KEY = 'youtube-speed-value'; const SPEED_STEP = 0.1; let speedDisplay = null; let isInitialized = false; // Debounce function to limit execution frequency function debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } function initSpeedControl() { if (isInitialized) return; const video = document.querySelector('video'); const timeDisplay = document.querySelector('.ytp-time-display'); if (!video || !timeDisplay) return; // Create speed display if not exists if (!speedDisplay) { speedDisplay = document.createElement('span'); speedDisplay.style.marginLeft = '10px'; timeDisplay.appendChild(speedDisplay); } // Apply saved speed const savedSpeed = parseFloat(localStorage.getItem(STORAGE_KEY)) || 1.0; video.playbackRate = savedSpeed; updateDisplay(savedSpeed); // Show guide only once per session if (!sessionStorage.getItem('guide-shown')) { showTemporaryGuide(); sessionStorage.setItem('guide-shown', 'true'); } isInitialized = true; } // Simplified speed display update function updateDisplay(speed) { if (speedDisplay) { speedDisplay.textContent = speed === 1 ? '' : `${speed.toFixed(1)}x`; } } // Optimized speed indicator function showSpeedIndicator(speed) { const bezel = document.querySelector('.ytp-bezel-text'); if (!bezel) return; const container = bezel.parentNode.parentNode; bezel.textContent = `${speed.toFixed(1)}x`; container.style.display = ''; setTimeout(() => container.style.display = 'none', 500); } // Simplified guide function showTemporaryGuide() { const guide = document.createElement('div'); guide.innerHTML = ` <div style="position:fixed;bottom:20px;right:20px;background:rgba(0,0,0,0.8); color:white;padding:12px;border-radius:6px;z-index:9999;font-family:Arial"> <div>Speed Controls:</div> <div>] - Speed up</div> <div>[ - Slow down</div> <div>p - Reset to 1x</div> </div> `; document.body.appendChild(guide); setTimeout(() => guide.remove(), 5000); } // Efficient keyboard handler function handleKeypress(e) { if (document.activeElement.tagName === 'INPUT') return; const video = document.querySelector('video'); if (!video) return; let newSpeed = video.playbackRate; switch(e.key) { case ']': newSpeed = Math.min(16, newSpeed + SPEED_STEP); break; case '[': newSpeed = Math.max(0.1, newSpeed - SPEED_STEP); break; case 'p': newSpeed = 1.0; break; default: return; } video.playbackRate = newSpeed; localStorage.setItem(STORAGE_KEY, newSpeed.toString()); updateDisplay(newSpeed); showSpeedIndicator(newSpeed); } // Optimized initialization function init() { // Remove any existing event listeners document.removeEventListener('keydown', handleKeypress); // Add single event listener for keyboard controls document.addEventListener('keydown', handleKeypress); // Debounced initialization for navigation changes const debouncedInit = debounce(() => { if (window.location.pathname.includes('/watch')) { isInitialized = false; initSpeedControl(); } }, 1000); // Listen for URL changes let lastUrl = location.href; new MutationObserver(() => { if (location.href !== lastUrl) { lastUrl = location.href; debouncedInit(); } }).observe(document, {subtree: true, childList: true}); // Initial setup debouncedInit(); } // Start the script if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址