您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
自动切换到你预先设定的播放速度。
// ==UserScript== // @name Youtube Remember Speed // @name:zh-TW YouTube 播放速度記憶 // @name:zh-CN YouTube 播放速度记忆 // @name:ja YouTube 再生速度メモリー // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAAAqhJREFUaEPtmc9rE0EUxz+DjSh6UAQRxP4F9uhBRKjipef+FwqtoZdYEk3U4jGn0FJ6KrQnj6X0EKVKKIi9tAotPZSCYilFoq0/sK1Z92V329XGENiZSRZ2LtllZ9+8z/e9ncy8UcS8qZj7TwLQ7ggmEUgiEFGB/6aQAxeBq8Al4GxonDPAydD9+dB1qkFfefy9iZ9fgRrwC/jh96v6vz+Bj8B7BduNbBwDcOA6UABuAyciCqTr9d/ACxf0oYI3YaOHAA71KfWpq8QDF6BTP27H9/GRArk+ctSBZ0BGl2SG7YwoyB4COF66lDtY+X/1EPVvKXhVTxUHKsANw6rpNl9RcFM50A1sxEj9QAiJQrcA9LvT5XPd8liy1y8Ad4GSpQF1D3NPAO4DRd2WLdlL6wUYH4dKBSYnLfmPZoDZWejrg/l5GByE5WXTIIYAxO1aDaamYGgIthsuY3TAGQQI3KtWoVCAUgkODnQ4HbZhASAYbnUV0mmYm9MJYREgcHtmxvs+1td1gLQBQNze24OxMchmYXc3CkibAOQDl6k2k4GtrZgBLC56KbSwEMXx4F2LEdjchHweJia8KVZPswCwvw+jo5DLwc6OHrePrBgGKJdhYABWVnQ7bjiF1ta8OV+WFmab5ghMT8PSEhSL3lRpvmkGSKVAct5eqwPEfkMT+y3lZeBDbDf1kq6xLqv4AL3AyxhFQUoqvQpeh2ujI+46cdjeBBJppL9Li34UBCYP5Do4ErKIeiLV82PF3UAPB64Bj4E7biW4K5JO+l6WvajUbqW8/jZsttkBxwWgB7gCnPZfCg4z5P6UH6lzTfyUgxGp7ctBRdBkBxNsjiWXv4Seyd93+DDkG/AJeKfgc6NxOvUcoOXYJQAtS2WoYxIBQ8K2bDaJQMtSGer4B8aT1sve/dr7AAAAAElFTkSuQmCC // @author ElectroKnight22 // @namespace electroknight22_youtube_remember_playback_rate_namespace // @version 1.1.1 // @match *://*.youtube.com/* // @exclude *://www.youtube.com/live_chat* // @grant GM.getValue // @grant GM.setValue // @grant GM.deleteValue // @grant GM.listValues // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @license MIT // @description Automcatically switches to your pre-selected speed. // @description:zh-TW 自動切換到你預先設定的播放速度。 // @description:zh-CN 自动切换到你预先设定的播放速度。 // @description:ja 自動的に設定した再生速度に替わります。 // ==/UserScript== /*jshint esversion: 11 */ (function() { "use strict"; const DEBUG = false; const DEFAULT_SETTINGS = { useNativeController: true, targetSpeed: 1 }; const speeds = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2]; let userSettings = { ...DEFAULT_SETTINGS }; let menuCommandIds = []; // To store main menu commands let menuOptionIds = []; // To store speed options let doc = document, win = window; function debugLog(message, shouldShow = true) { if (DEBUG && shouldShow) { console.log("YTRS DEBUG | " + message); } } // Functions to set the playbackRate function setSpeed(targetSpeed) { debugLog("Mode: " + userSettings.useNativeController); debugLog("Trying to set speed to: " + targetSpeed + "x"); userSettings.useNativeController? setSpeedNative(targetSpeed) : setSpeedHtml(targetSpeed); } function setSpeedNative(targetSpeed) { let ytPlayer = doc.getElementById("movie_player") || doc.getElementsByClassName("html5-video-player")[0]; if (!isValidVideo(ytPlayer)) return; ytPlayer.setPlaybackRate(targetSpeed); } function setSpeedHtml(targetSpeed) { try { let video = doc.querySelector('video'); video.playbackRate = targetSpeed; } catch (error) { debugLog("[HTML MODE] Error when trying to set speed. Error: " + error); } } function isValidVideo(ytPlayer) { if (win.location.href.startsWith("https://www.youtube.com/shorts/")) { debugLog("Skipping Youtube Shorts"); return false; } if (!ytPlayer?.getAvailableQualityLabels()[0]) { debugLog("Video data missing"); return false; } return true; } // functions to create the option menu function createSpeedMenu() { // Register the speed menu command menuCommandIds.push(GM_registerMenuCommand("Set Speed (show/hide)", () => { menuOptionIds.length ? removeSpeedMenuItems() : showSpeedMenuItems(); }, { autoClose: false })); // Register the dynamic controller command registerNativeSpeedControllerCommand(); } function registerNativeSpeedControllerCommand() { // Remove the old controller command if it exists if (menuCommandIds.length > 1) { GM_unregisterMenuCommand(menuCommandIds.pop()); } // Register the new controller command with the updated label const controllerCommandId = GM_registerMenuCommand(userSettings.useNativeController ? "Using Native Speed Controller (toggle)" : "Bypassing Native Speed Controller (toggle)", () => { userSettings.useNativeController = !userSettings.useNativeController; GM.setValue('useNativeController', userSettings.useNativeController); registerNativeSpeedControllerCommand(); // Update the menu item label }, { autoClose: false }); // Add the updated command ID to the list menuCommandIds.push(controllerCommandId); if (menuOptionIds.length) { removeSpeedMenuItems(); showSpeedMenuItems(); } } function showSpeedMenuItems() { removeSpeedMenuItems(); let speedList = speeds; if (!userSettings.useNativeController) { speedList = []; for (let i = 0; i <= 16; i += 0.125) { speedList.push(i); } } speedList.forEach((speed) => { let speedText = speed + "x"; if (speed === userSettings.targetSpeed) { speedText += " (selected)"; } const speedCommandId = GM_registerMenuCommand(speedText, () => { setSelectedSpeed(speed); }, { autoClose: false, }); menuOptionIds.push(speedCommandId); }); } function removeSpeedMenuItems() { while (menuOptionIds.length) { GM_unregisterMenuCommand(menuOptionIds.pop()); } } function setSelectedSpeed(speed) { if (userSettings.targetSpeed == speed) return; userSettings.targetSpeed = speed; GM.setValue('targetSpeed', speed); removeSpeedMenuItems(); showSpeedMenuItems(); setSpeed(speed); } // syncs the user's settings on load async function applySettings() { try { const storedValues = await GM.listValues(); await Promise.all(Object.entries(DEFAULT_SETTINGS).map(async ([key, value]) => { if (!storedValues.includes(key)) { await GM.setValue(key, value); } })); await Promise.all(storedValues.map(async key => { if (!(key in DEFAULT_SETTINGS)) { await GM.deleteValue(key); } })); await Promise.all( storedValues.map(key => GM.getValue(key).then(value => [key, value])) ).then(keyValuePairs => keyValuePairs.forEach(([newKey, newValue]) => { userSettings[newKey] = newValue; })); debugLog(Object.entries(userSettings).map(([key, value]) => key + ": " + value).join(", ")); } catch (error) { debugLog("Error when applying settings: " + error.message); } } function main() { if (win.self == win.top) { createSpeedMenu(); } setSpeed(userSettings.targetSpeed); win.addEventListener("loadstart", () => { setSpeed(userSettings.targetSpeed); }, true); } applySettings().then(main); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址