您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
在BiliBili视频播放页面上,提供用户选项来自动进入网页全屏和/或关灯模式。
// ==UserScript== // @name BiliBili自动网页全屏和关灯 // @namespace http://tampermonkey.net/ // @version 2.7 // @description 在BiliBili视频播放页面上,提供用户选项来自动进入网页全屏和/或关灯模式。 // @author two cold // @match https://www.bilibili.com/video/* // @grant GM_getValue // @grant GM_setValue // @grant GM_registerMenuCommand // @grant GM_addStyle // @license MIT // ==/UserScript== (function() { 'use strict'; // --- UI & Notifications --- GM_addStyle(` .gm-toast-container { position: fixed; top: 20px; right: 20px; z-index: 99999; display: flex; flex-direction: column; align-items: flex-end; } .gm-toast { padding: 10px 20px; margin-bottom: 10px; background-color: #00a1d6; /* Bilibili blue */ color: white; border-radius: 5px; opacity: 0; transition: opacity 0.4s ease-in-out, transform 0.4s ease-in-out; font-family: sans-serif; font-size: 14px; transform: translateX(100%); } `); const toastContainer = document.createElement('div'); toastContainer.className = 'gm-toast-container'; document.body.appendChild(toastContainer); function showToast(message) { const toast = document.createElement('div'); toast.className = 'gm-toast'; toast.textContent = message; toastContainer.appendChild(toast); setTimeout(() => { toast.style.opacity = 1; toast.style.transform = 'translateX(0)'; }, 10); // Display for 5 seconds setTimeout(() => { toast.style.opacity = 0; toast.style.transform = 'translateX(100%)'; setTimeout(() => toast.remove(), 400); }, 5000); } // --- Configuration --- const CONFIG_WEBFULLSCREEN_KEY = 'config_auto_web_fullscreen'; const CONFIG_LIGHTSOFF_KEY = 'config_lights_off'; let enableAutoWebFullscreen = GM_getValue(CONFIG_WEBFULLSCREEN_KEY, true); let enableLightsOff = GM_getValue(CONFIG_LIGHTSOFF_KEY, false); GM_registerMenuCommand(`自动网页全屏: ${enableAutoWebFullscreen ? '✅' : '❌'}`, () => { enableAutoWebFullscreen = !enableAutoWebFullscreen; GM_setValue(CONFIG_WEBFULLSCREEN_KEY, enableAutoWebFullscreen); showToast(`自动网页全屏已${enableAutoWebFullscreen ? '开启' : '关闭'},刷新页面后生效`); }); GM_registerMenuCommand(`自动关灯模式: ${enableLightsOff ? '✅' : '❌'}`, () => { enableLightsOff = !enableLightsOff; GM_setValue(CONFIG_LIGHTSOFF_KEY, enableLightsOff); showToast(`自动关灯模式已${enableLightsOff ? '开启' : '关闭'},刷新页面后生效`); }); // --- Core Logic --- let scriptExecuted = false; let lastExecutionTime = 0; const MIN_EXECUTION_INTERVAL = 5000; function waitForElement(selector, callback, maxAttempts = 50) { let attempts = 0; const interval = setInterval(() => { const element = document.querySelector(selector); if (element || attempts >= maxAttempts) { clearInterval(interval); if (element) { callback(element); } } attempts++; }, 200); } function debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } function canExecute() { const currentTime = Date.now(); if (scriptExecuted && (currentTime - lastExecutionTime) < MIN_EXECUTION_INTERVAL) { console.log('执行间隔太短,跳过执行'); return false; } return true; } function isAlreadyInWebFullscreen() { return document.querySelector('.bilibili-player-video-web-fullscreen') || document.querySelector('.bpx-player-state-web-fullscreen'); } function enterWebFullscreen() { if (isAlreadyInWebFullscreen()) { console.log('已处于网页全屏状态,跳过'); return; } const fullscreenBtn = document.querySelector('.bpx-player-ctrl-btn.bpx-player-ctrl-web') || document.querySelector('[aria-label="网页全屏"]'); if (fullscreenBtn) { console.log('找到并点击网页全屏按钮'); fullscreenBtn.click(); } else { console.log('未找到网页全屏按钮'); } } async function enterLightsOffMode() { console.log('尝试进入关灯模式...'); if (document.querySelector('.bpx-player-mode-lightsoff') || document.body.classList.contains('player-mode-blackmask')) { console.log('已处于关灯模式,跳过'); return; } const settingsBtn = document.querySelector('.bpx-player-ctrl-setting') || document.querySelector('.bilibili-player-video-btn-setting'); if (!settingsBtn) { console.log('未找到设置按钮'); return; } settingsBtn.click(); await new Promise(r => setTimeout(r, 300)); const lightOffSwitch = document.querySelector('input[aria-label="关灯模式"]'); if (lightOffSwitch) { if (!lightOffSwitch.checked) { console.log('找到并点击“关灯模式”开关'); lightOffSwitch.click(); } } settingsBtn.click(); } function main() { if (!canExecute()) return; console.log('Bilibili 助手脚本启动'); scriptExecuted = true; lastExecutionTime = Date.now(); waitForElement('.bilibili-player, .bpx-player-container, #bilibiliPlayer', () => { console.log('播放器已加载'); if (enableAutoWebFullscreen) { console.log('准备进入网页全屏'); setTimeout(enterWebFullscreen, 1500); } if (enableLightsOff) { console.log('准备进入关灯模式'); setTimeout(enterLightsOffMode, 2500); } }); } const debouncedMain = debounce(main, 3000); if (document.readyState === 'complete' || document.readyState === 'interactive') { debouncedMain(); } else { document.addEventListener('DOMContentLoaded', debouncedMain); } let lastUrl = location.href; const observer = new MutationObserver(() => { if (location.href !== lastUrl) { const currentVideoId = location.href.match(/\/video\/(BV\w+)/); const lastVideoId = lastUrl.match(/\/video\/(BV\w+)/); if (currentVideoId && (!lastVideoId || currentVideoId[1] !== lastVideoId[1])) { console.log('检测到新视频,重置状态并执行'); scriptExecuted = false; setTimeout(debouncedMain, 1500); } lastUrl = location.href; } }); observer.observe(document, { subtree: true, childList: true }); })();