// ==UserScript== // @name HTML5视频倍速 // @namespace http://tampermonkey.net/ // @version 1.0.3 // @description 精准控制视频速度不跳帧(1=1x, 2=2x, 3=3x) // @author 重庆吴亦凡 // @match *://*/* // @grant none // @downloadURL https://update.greasyfork.icu/scripts/531037/HTML5%E8%A7%86%E9%A2%91%E5%80%8D%E9%80%9F.user.js // @updateURL https://update.greasyfork.icu/scripts/531037/HTML5%E8%A7%86%E9%A2%91%E5%80%8D%E9%80%9F.meta.js // ==/UserScript== (function() { 'use strict'; // 更稳定的样式注入 const style = document.createElement('style'); style.textContent = ` .speed-hud { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: rgba(0,0,0,0.8); color: white; padding: 12px 24px; border-radius: 8px; font-size: 18px; font-family: Arial; z-index: 99999; opacity: 0; transition: opacity 0.3s; } .speed-hud.show { opacity: 1; } `; document.head.appendChild(style); class VideoMaster { constructor() { this.speeds = {'1':1.0, '2':2.0, '3':3.0}; this.hud = this.createHUD(); this.currentVideo = null; this.observer = new MutationObserver(() => this.detectVideo()); this.detectVideo(); } createHUD() { const hud = document.createElement('div'); hud.className = 'speed-hud'; document.body.appendChild(hud); return hud; } detectVideo() { // 优先选择正在播放的视频 const videos = Array.from(document.querySelectorAll('video')); this.currentVideo = videos.find(v => !v.paused) || videos[0]; // 自动监控iframe内的视频 if (!this.currentVideo) { document.querySelectorAll('iframe').forEach(iframe => { try { const iframeDoc = iframe.contentDocument; if (iframeDoc) { const iframeVideos = iframeDoc.querySelectorAll('video'); if (iframeVideos.length) { this.currentVideo = iframeVideos[0]; } } } catch (e) {} }); } // 开始观察DOM变化 if (!this.observer) { this.observer = new MutationObserver(() => this.detectVideo()); this.observer.observe(document.body, { childList: true, subtree: true }); } } setSpeed(speed) { if (!this.currentVideo) { this.detectVideo(); if (!this.currentVideo) return false; } // 保存当前播放时间(避免跳帧) const currentTime = this.currentVideo.currentTime; const wasPaused = this.currentVideo.paused; this.currentVideo.playbackRate = speed; this.currentVideo.currentTime = currentTime; // 锁定时间点 if (!wasPaused) { this.currentVideo.play().catch(e => console.log(e)); } this.showHUD(`${speed}x`); return true; } showHUD(text) { this.hud.textContent = `速度: ${text}`; this.hud.classList.add('show'); clearTimeout(this.hudTimer); this.hudTimer = setTimeout(() => { this.hud.classList.remove('show'); }, 1000); } } const vm = new VideoMaster(); // 强化版事件监听 document.addEventListener('keydown', function(e) { // 排除输入框/可编辑区域 if (['INPUT','TEXTAREA'].includes(document.activeElement.tagName) || document.activeElement.isContentEditable) return; // 只响应独立数字键(不响应组合键) if (['1','2','3'].includes(e.key) && !e.ctrlKey && !e.altKey && !e.metaKey) { e.stopImmediatePropagation(); e.preventDefault(); // 确保视频已加载 if (!vm.currentVideo || vm.currentVideo.readyState < 2) { vm.detectVideo(); if (!vm.currentVideo) return; } vm.setSpeed(vm.speeds[e.key]); } }, true); // 使用捕获阶段确保优先处理 })();