// ==UserScript== // @name 视频快捷键控制器 // @namespace http://tampermonkey.net/ // @version 1.0 // @description 为页面中的视频添加播放快捷键 (加速 Z, 快进 X, 快退 C - 可配置)。支持自定义快捷键和播放速度。 // @author Triumph // @match *://*/* // @grant GM_getValue // @grant GM_setValue // @grant GM_registerMenuCommand // @run-at document-idle // @license MIT // @downloadURL https://update.greasyfork.icu/scripts/533328/%E8%A7%86%E9%A2%91%E5%BF%AB%E6%8D%B7%E9%94%AE%E6%8E%A7%E5%88%B6%E5%99%A8.user.js // @updateURL https://update.greasyfork.icu/scripts/533328/%E8%A7%86%E9%A2%91%E5%BF%AB%E6%8D%B7%E9%94%AE%E6%8E%A7%E5%88%B6%E5%99%A8.meta.js // ==/UserScript== (function() { 'use strict'; // 全局变量 let currentVideoElement = null; let isShortcutKeyPressed = { accelerate: false }; let observer = null; // 快捷键设置 const defaultSettings = { accelerationRate: 3, skipTime: 5, keys: { accelerate: 'z', forward: 'x', backward: 'c' } }; // 获取设置 function getSettings() { return { accelerationRate: parseFloat(GM_getValue('accelerationRate', defaultSettings.accelerationRate)), skipTime: parseFloat(GM_getValue('skipTime', defaultSettings.skipTime)), keys: { accelerate: GM_getValue('accelerateKey', defaultSettings.keys.accelerate), forward: GM_getValue('forwardKey', defaultSettings.keys.forward), backward: GM_getValue('backwardKey', defaultSettings.keys.backward) } }; } // 保存设置 function saveSettings(settings) { GM_setValue('accelerationRate', settings.accelerationRate); GM_setValue('skipTime', settings.skipTime); GM_setValue('accelerateKey', settings.keys.accelerate); GM_setValue('forwardKey', settings.keys.forward); GM_setValue('backwardKey', settings.keys.backward); } // 查找视频元素 function findVideoElement() { const videos = document.querySelectorAll('video.jw-video, video'); if (videos.length === 0) return null; let bestVideo = null; let maxSize = 0; videos.forEach((video) => { if (video.offsetParent === null) return; const rect = video.getBoundingClientRect(); if (rect.width < 100 || rect.height < 100) return; if (video.classList.contains('jw-video')) { bestVideo = video; return; } const currentSize = rect.width * rect.height; if (currentSize > maxSize) { maxSize = currentSize; bestVideo = video; } }); if (!bestVideo && videos.length > 0) { for(let video of videos) { if(video.readyState > 0 || video.currentSrc) { bestVideo = video; break; } } if(!bestVideo) bestVideo = videos[0]; } return bestVideo; } // 设置快捷键监听 function setupShortcuts() { if (document.body.dataset.shortcutListenersAttached === 'true') { return; } document.addEventListener('keydown', (e) => { if (!currentVideoElement || e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.isContentEditable) { return; } const key = e.key.toLowerCase(); const keys = getSettings().keys; let preventDefault = false; if (key === keys.accelerate) { if (!isShortcutKeyPressed.accelerate) { if(currentVideoElement.playbackRate !== getSettings().accelerationRate) { currentVideoElement.playbackRate = getSettings().accelerationRate; } isShortcutKeyPressed.accelerate = true; } preventDefault = true; } else if (key === keys.forward) { currentVideoElement.currentTime += getSettings().skipTime; preventDefault = true; } else if (key === keys.backward) { currentVideoElement.currentTime -= getSettings().skipTime; preventDefault = true; } if (preventDefault) { e.preventDefault(); e.stopPropagation(); } }); document.addEventListener('keyup', (e) => { if (!currentVideoElement) return; const key = e.key.toLowerCase(); const keys = getSettings().keys; if (key === keys.accelerate && isShortcutKeyPressed.accelerate) { if (currentVideoElement.playbackRate === getSettings().accelerationRate) { currentVideoElement.playbackRate = 1.0; } isShortcutKeyPressed.accelerate = false; } }); document.body.dataset.shortcutListenersAttached = 'true'; } // 注册菜单命令 function registerMenuCommands() { GM_registerMenuCommand("设置快捷键", () => { const settings = getSettings(); const html = `