您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
分段倍速调节,提示显示在播放器底部中间,支持B站宽屏切换,YouTube字幕键屏蔽等功能。
// ==UserScript== // @name B站/Youtube 倍速快捷键(Z/X/C)+ 宽屏提示(中下方居中) // @version 1.1 // @description 分段倍速调节,提示显示在播放器底部中间,支持B站宽屏切换,YouTube字幕键屏蔽等功能。 // @author 重音(support by GPT) // @match https://www.bilibili.com/* // @match https://www.youtube.com/* // @grant GM_setValue // @grant GM_getValue // @license GPL // @namespace https://greasyfork.org/users/1476609 // ==/UserScript== (function () { "use strict"; let isActive = 1; let video = null; let currentRate = GM_getValue("a", 10); let lastRate = GM_getValue("b", 10); function updateVideoElement() { video = document.querySelector("video") || document.querySelector("bwp-video"); } function setupFocusHandlers() { const inputs = [ document.querySelector(".reply-box-textarea"), document.querySelector(".bpx-player-dm-input"), document.querySelector(".nav-search-input") ]; inputs.forEach(input => { if (input) { input.addEventListener("focus", () => isActive = 0); input.addEventListener("blur", () => isActive = 1); } }); } window.addEventListener("load", () => { updateVideoElement(); setupFocusHandlers(); }); new MutationObserver(() => { updateVideoElement(); setupFocusHandlers(); }).observe(document.body, { childList: true, subtree: true }); setInterval(() => { if (video) { video.playbackRate = currentRate / 10; } }, 600); // ✅ 创建气泡提示容器(底部中间靠上) const tip = document.createElement("div"); tip.style.cssText = ` position: absolute; left: 50%; bottom: 45px; transform: translateX(-50%); background: rgba(0, 0, 0, 0.75); color: #fff; padding: 6px 12px; border-radius: 8px; font-size: 14px; z-index: 99999; opacity: 0; transition: opacity 0.3s; pointer-events: none; `; function attachTipToPlayer() { const player = document.querySelector(".bpx-player-container") || document.querySelector(".html5-video-player") || document.querySelector("video")?.parentElement; if (player && player.appendChild && !tip.parentElement) { if (getComputedStyle(player).position === "static") { player.style.position = "relative"; } player.appendChild(tip); } } attachTipToPlayer(); setInterval(attachTipToPlayer, 1000); let tipTimer = null; function showTip(text) { tip.textContent = text; tip.style.opacity = "1"; clearTimeout(tipTimer); tipTimer = setTimeout(() => { tip.style.opacity = "0"; }, 1200); } function getStep(rate10) { const real = rate10 / 10; if (real < 2) return 2; if (real < 4) return 5; return 10; } document.addEventListener("keydown", function (e) { if (!isActive) return; const key = e.code; const isBili = location.hostname.includes("bilibili.com"); const isYouTube = location.hostname.includes("youtube.com"); // 屏蔽 YouTube 原生 C 字幕快捷键 if (isYouTube && key === "KeyC") { e.stopImmediatePropagation(); e.preventDefault(); } if (!video) return; currentRate = Math.round(10 * video.playbackRate); const step = getStep(currentRate); let changed = false; if (key === "KeyX") { e.preventDefault(); currentRate -= step; changed = true; } else if (key === "KeyC") { e.preventDefault(); currentRate += step; changed = true; } else if (key === "KeyZ") { e.preventDefault(); currentRate = video.playbackRate === 1.0 ? lastRate : 10; changed = true; } else if (key === "KeyT") { if (isBili) { e.preventDefault(); // 仅 B 站拦截 const wideBtn = document.querySelector(".bpx-player-ctrl-wide"); if (wideBtn) { wideBtn.click(); } } } currentRate = Math.max(2, Math.min(currentRate, 80)); if (changed) { GM_setValue("a", currentRate); if (key !== "KeyZ") { lastRate = currentRate; GM_setValue("b", lastRate); } video.playbackRate = currentRate / 10; showTip(`播放速度:${(currentRate / 10).toFixed(1)}x`); } }, true); setInterval(() => { const rateDisplay = document.querySelector(".bpx-player-ctrl-playbackrate-result"); if (rateDisplay) { const val = parseFloat(rateDisplay.textContent.replace("x", "")); if (!isNaN(val)) { currentRate = Math.round(val * 10); GM_setValue("a", currentRate); } } }, 2000); })();