手动激活后设置视频倍速,支持刷新和切换视频时自动应用,右下角显示一个迷你控制面板。每次调整步进为0.5。
// ==UserScript==
// @name 视频倍速调节 v2.2 (迷你界面)
// @namespace http://tampermonkey.net/
// @version 2.2
// @description 手动激活后设置视频倍速,支持刷新和切换视频时自动应用,右下角显示一个迷你控制面板。每次调整步进为0.5。
// @author AI助手 & Gemini
// @match *://*/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_registerMenuCommand
// @license MIT
// ==/UserScript==
(function () {
'use strict';
// --- 配置常量 ---
const MAX_SPEED = 16.0;
const MIN_SPEED = 0.5;
const STEP = 0.5; // 每次调整的步进
const STORAGE_KEY_SPEED = 'videoPlaybackSpeed_v2';
const STORAGE_KEY_SITES = 'videoSpeedActiveSites_v2';
// --- 全局变量 ---
let currentSpeed = parseFloat(GM_getValue(STORAGE_KEY_SPEED, 2.0));
let activatedSites = GM_getValue(STORAGE_KEY_SITES, []);
let controlPanel;
// --- SVG 图标 (再次缩小) ---
const SVG_ARROW_UP = `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" style="width: 14px; height: 14px;"><path d="M5 15.5L12 8.5L19 15.5" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
const SVG_ARROW_DOWN = `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" style="width: 14px; height: 14px;"><path d="M19 8.5L12 15.5L5 8.5" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
// --- 核心功能 ---
const getDomain = () => location.hostname;
const isSiteActivated = () => activatedSites.includes(getDomain());
function activateSite() {
const domain = getDomain();
if (!activatedSites.includes(domain)) {
activatedSites.push(domain);
GM_setValue(STORAGE_KEY_SITES, activatedSites);
if (controlPanel && !document.body.contains(controlPanel)) {
document.body.appendChild(controlPanel);
}
updatePanelUI();
setVideoSpeed();
}
}
function deactivateSite() {
const domain = getDomain();
activatedSites = activatedSites.filter(site => site !== domain);
GM_setValue(STORAGE_KEY_SITES, activatedSites);
if (controlPanel) {
updatePanelUI();
}
document.querySelectorAll('video').forEach(video => video.playbackRate = 1.0);
}
function setVideoSpeed() {
if (!isSiteActivated()) return;
document.querySelectorAll('video').forEach(video => {
if (video.playbackRate !== currentSpeed) {
video.playbackRate = currentSpeed;
}
});
}
function updateSpeed(change) {
if (!isSiteActivated()) return;
let newSpeed = parseFloat((currentSpeed + change).toPrecision(12));
currentSpeed = Math.min(MAX_SPEED, Math.max(MIN_SPEED, newSpeed));
GM_setValue(STORAGE_KEY_SPEED, currentSpeed);
updatePanelUI();
setVideoSpeed();
}
// --- UI 相关 ---
function injectStyles() {
const style = document.createElement('style');
style.textContent = `
.speed-panel-container {
position: fixed;
bottom: 10px; /* <--- 修改点:更贴近角落 */
right: 10px; /* <--- 修改点:更贴近角落 */
width: 75px; /* <--- 修改点:进一步减小宽度 */
background-color: rgba(28, 28, 30, 0.85);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
color: #FEFEFE;
padding: 6px; /* <--- 修改点:减小内边距 */
border-radius: 8px;
z-index: 2147483647;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
gap: 6px; /* <--- 修改点:减小间距 */
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
border: 1px solid rgba(255, 255, 255, 0.1);
}
.speed-panel-display {
font-size: 14px; /* <--- 修改点:减小字体 */
font-weight: 600;
}
.speed-panel-controls {
display: flex;
justify-content: center;
gap: 6px;
}
.speed-panel-btn {
width: 28px; /* <--- 修改点:减小按钮尺寸 */
height: 28px; /* <--- 修改点:减小按钮尺寸 */
display: flex;
justify-content: center;
align-items: center;
background-color: rgba(255, 255, 255, 0.1);
border: none;
border-radius: 50%;
cursor: pointer;
transition: background-color 0.2s ease;
}
.speed-panel-btn:hover {
background-color: rgba(255, 255, 255, 0.2);
}
.speed-panel-btn:disabled {
opacity: 0.4;
cursor: not-allowed;
}
.speed-panel-toggle {
width: 100%;
padding: 4px 0;
font-size: 12px;
font-weight: 500;
border: none;
border-radius: 6px;
cursor: pointer;
transition: background-color 0.2s ease;
}
`;
document.head.appendChild(style);
}
function createPanelDOM() {
controlPanel = document.createElement('div');
controlPanel.className = 'speed-panel-container';
const speedDisplay = document.createElement('div');
speedDisplay.className = 'speed-panel-display';
const controlsContainer = document.createElement('div');
controlsContainer.className = 'speed-panel-controls';
const upButton = document.createElement('button');
upButton.className = 'speed-panel-btn';
upButton.innerHTML = SVG_ARROW_UP;
upButton.addEventListener('click', () => updateSpeed(STEP));
const downButton = document.createElement('button');
downButton.className = 'speed-panel-btn';
downButton.innerHTML = SVG_ARROW_DOWN;
downButton.addEventListener('click', () => updateSpeed(-STEP));
controlsContainer.append(upButton, downButton);
const toggleButton = document.createElement('button');
toggleButton.className = 'speed-panel-toggle';
toggleButton.addEventListener('click', () => {
isSiteActivated() ? deactivateSite() : activateSite();
});
controlPanel.append(speedDisplay, controlsContainer, toggleButton);
}
function updatePanelUI() {
if (!controlPanel) return;
const activated = isSiteActivated();
const ui = {
display: controlPanel.querySelector('.speed-panel-display'),
upBtn: controlPanel.querySelectorAll('.speed-panel-btn')[0],
downBtn: controlPanel.querySelectorAll('.speed-panel-btn')[1],
toggleBtn: controlPanel.querySelector('.speed-panel-toggle'),
};
ui.display.innerText = activated ? `${currentSpeed.toFixed(1)}x` : '已关闭';
ui.toggleBtn.innerText = activated ? '关闭' : '激活';
ui.toggleBtn.style.backgroundColor = activated ? 'rgba(239, 68, 68, 0.7)' : 'rgba(34, 197, 94, 0.7)';
ui.upBtn.disabled = !activated;
ui.downBtn.disabled = !activated;
}
// --- 启动逻辑 ---
function initialize() {
injectStyles();
createPanelDOM();
if (isSiteActivated()) {
document.body.appendChild(controlPanel);
setVideoSpeed();
const observer = new MutationObserver(setVideoSpeed);
observer.observe(document.body, { childList: true, subtree: true });
setInterval(setVideoSpeed, 1000);
}
updatePanelUI();
document.addEventListener('keydown', (event) => {
if (event.altKey && isSiteActivated()) {
if (event.key === 'ArrowUp') updateSpeed(STEP);
if (event.key === 'ArrowDown') updateSpeed(-STEP);
}
});
}
// 注册(不可用)菜单
GM_registerMenuCommand('激活当前网站视频倍速', () => {
if (isSiteActivated()) {
alert('当前网站已激活!');
return;
}
activateSite();
alert(`已为 ${getDomain()} 激活视频倍速`);
});
GM_registerMenuCommand('取消当前网站视频倍速', () => {
if (!isSiteActivated()) {
alert('当前网站未激活!');
return;
}
deactivateSite();
alert(`已为 ${getDomain()} 取消视频倍速`);
});
// 等待页面加载完成
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initialize);
} else {
initialize();
}
})();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址