您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Undo and redo changes in playback position on YouTube
当前为
// ==UserScript== // @name YouTube Undo // @description Undo and redo changes in playback position on YouTube // @version 0.2.0 // @author Adam Thompson-Sharpe // @namespace MysteryBlokHed // @license GPL-3.0 // @copyright 2022 Adam Thomspon-Sharpe // @homepageURL https://gitlab.com/MysteryBlokHed/userscripts/-/tree/main/YouTubeUndo // @supportURL https://gitlab.com/MysteryBlokHed/userscripts/-/issues // @match *://*.youtube.com/watch* // @grant none // ==/UserScript== ;(() => { var _a /** Whether to log basic debug events */ const DEBUG_LOGS = false const debug = DEBUG_LOGS ? (...args) => console.debug('[YouTube Undo]', ...args) : () => {} /** The interval **in seconds** to check the player's current time */ const ROUGH_TIME_RATE = 2 /** Keep track of the current player time while no events are in the array */ let roughTime = 0 setInterval(() => { const currentTime = player.getCurrentTime() roughTime = currentTime }, ROUGH_TIME_RATE * 1000) /** * Track the index in the array that matches the current state of undo's/redo's. * Used to allow undoing and redoing back and forth */ let undoPoint = -1 /** Time change events */ const timeChanges = [] const addChange = change => { debug('Adding change event to', timeChanges) timeChanges.length = undoPoint + 1 timeChanges.push(change) undoPoint = timeChanges.length - 1 debug('After:', timeChanges) } /** The current time change event, using `undoPoint` */ const currentChange = () => { var _a return (_a = timeChanges[undoPoint]) !== null && _a !== void 0 ? _a : null } /** The last time change event in the list */ const lastChange = () => timeChanges.length ? timeChanges[timeChanges.length - 1] : null /** Get the last change's time if it exists, otherwise use the rough time */ const lastOrRough = () => { var _a, _b return (_b = (_a = lastChange()) === null || _a === void 0 ? void 0 : _a.after) !== null && _b !== void 0 ? _b : roughTime } // prettier-ignore const player = document.getElementById('movie_player'); if (!player) { console.error('[YouTube Undo]', 'Player not found!') return } // Clear events on location changes window.addEventListener('yt-navigate-finish', () => { timeChanges.length = 0 undoPoint = -1 debug('New video, clearing event list') }) // Watch for playbar clicks ;(_a = document.querySelector('div.ytp-progress-bar')) === null || _a === void 0 ? void 0 : _a.addEventListener('click', () => { const currentTime = player.getCurrentTime() addChange({ before: lastOrRough(), after: currentTime, }) roughTime = currentTime debug('Added time change for playbar seek', lastChange()) }) // Watch for keypresses window.addEventListener('keydown', ev => { if (ev.key.match(/^(?:\d|j|l|ArrowLeft|ArrowRight)$/i)) { // A key that might change the current time const last = lastChange() const currentTime = player.getCurrentTime() debug('Time-changing key pressed') debug('Last:', last) debug('Current:', currentTime) if (!last) debug('Rough Time:', roughTime) if ( (last === null || last === void 0 ? void 0 : last.after) !== currentTime ) { addChange({ before: lastOrRough(), after: currentTime, }) } } else if (ev.ctrlKey && ev.key.toLowerCase() === 'z') { // Ctrl + Z const undoTo = currentChange() debug('Ctrl + Z pressed') debug('Full list:', timeChanges) debug('Undoing to:', undoTo, 'at index', undoPoint) if (undoTo) player.seekTo(undoTo.before) if (undoPoint >= 0) undoPoint-- } else if (ev.ctrlKey && ev.key.toLowerCase() === 'y') { // Ctrl + Y if (undoPoint < timeChanges.length - 1) undoPoint++ const redoTo = currentChange() debug('Ctrl + Y pressed') debug('Full list:', timeChanges) debug('Redoing to:', redoTo, 'at index', undoPoint) if (redoTo) player.seekTo(redoTo.after) } }) })()