您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds playback speed control buttons and keyboard shortcuts to YouTube videos
// ==UserScript== // @name YouTube Playback Speed Buttons // @namespace https://youtube.com // @version 1.1 // @description Adds playback speed control buttons and keyboard shortcuts to YouTube videos // @author indistinctive // @match https://www.youtube.com/* // @icon https://www.google.com/s2/favicons?domain=youtube.com // @grant none // @run-at document-idle // @license GNU GPLv3 // ==/UserScript== (function() { 'use strict'; let activeButton = null; function createSpeedControls() { const player = document.querySelector('ytd-player'); const video = player ? player.querySelector('video') : null; if (!video) return; const controlsContainer = player.querySelector('.ytp-right-controls'); if (!controlsContainer) return; const speedButtonContainer = document.createElement('div'); speedButtonContainer.style.display = 'flex'; speedButtonContainer.style.alignItems = 'center'; speedButtonContainer.style.marginRight = '10px'; speedButtonContainer.style.zIndex = '9999'; // Speeds array with desired speeds const speeds = [1, 1.5, 2, 3]; speeds.forEach(speed => { const button = document.createElement('button'); button.innerText = `${speed}×`; button.style.padding = '4px 10px'; button.style.marginRight = '5px'; button.style.border = 'none'; button.style.backgroundColor = '#fff'; button.style.color = '#000'; button.style.cursor = 'pointer'; button.style.fontSize = '14px'; button.style.fontWeight = '500'; button.style.borderRadius = '5px'; button.style.transition = 'background-color 0.2s ease, color 0.2s ease'; button.style.boxShadow = 'none'; button.style.outline = 'none'; button.style.width = '40px'; button.style.display = 'flex'; button.style.justifyContent = 'center'; button.style.alignItems = 'center'; // Hover effect button.addEventListener('mouseenter', () => { if (button !== activeButton) { button.style.backgroundColor = '#000'; button.style.color = '#fff'; } }); button.addEventListener('mouseleave', () => { if (button !== activeButton) { button.style.backgroundColor = '#fff'; button.style.color = '#000'; } }); // Handle button click to change playback speed button.addEventListener('click', () => { video.playbackRate = speed; highlightButton(button); }); speedButtonContainer.appendChild(button); }); controlsContainer.style.display = 'flex'; controlsContainer.insertBefore(speedButtonContainer, controlsContainer.firstChild); } // Highlight the active speed button function highlightButton(button) { if (activeButton !== button) { if (activeButton) { activeButton.style.backgroundColor = '#fff'; activeButton.style.color = '#000'; } activeButton = button; button.style.backgroundColor = '#000'; button.style.color = '#fff'; } } // Listen for keyboard shortcuts document.addEventListener('keydown', (event) => { const player = document.querySelector('ytd-player'); const video = player ? player.querySelector('video') : null; if (!video || event.target.tagName.toLowerCase() === 'input' || event.target.tagName.toLowerCase() === 'textarea') { return; } switch (event.key.toLowerCase()) { case 'q': video.playbackRate = 1; updateActiveButton(1); break; case 's': video.playbackRate = 1.5; updateActiveButton(1.5); break; case 'w': video.playbackRate = 2; updateActiveButton(2); break; case 'e': video.playbackRate = 3; updateActiveButton(3); break; } }); // Update the active button based on playback speed function updateActiveButton(speed) { const player = document.querySelector('ytd-player'); const controlsContainer = player ? player.querySelector('.ytp-right-controls') : null; if (!controlsContainer) return; const buttons = controlsContainer.querySelectorAll('button'); buttons.forEach(button => { if (button.innerText === `${speed}×`) { highlightButton(button); } }); } function waitForPlayer() { const observer = new MutationObserver(() => { const player = document.querySelector('ytd-player'); const controlsContainer = player ? player.querySelector('.ytp-right-controls') : null; if (controlsContainer) { createSpeedControls(); observer.disconnect(); } }); observer.observe(document.body, { childList: true, subtree: true }); } waitForPlayer(); })();