您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
在所有网站(包括YouTube、TikTok、抖音、快手)上强制增强音量,支持Alt+s快捷键启用/禁用,Alt+5热重载脚本,Alt+↑/↓调节音量
当前为
// ==UserScript== // @name 通用音量增强器 - Universal Volume Booster // @namespace http://tampermonkey.net/ // @version 1.8 // @description 在所有网站(包括YouTube、TikTok、抖音、快手)上强制增强音量,支持Alt+s快捷键启用/禁用,Alt+5热重载脚本,Alt+↑/↓调节音量 // @author 醉春风制作 // @match *://*/* // @grant GM_setValue // @grant GM_getValue // @grant GM_addStyle // @run-at document-start // @license All Rights Reserved // ==/UserScript== /* 通用音量增强器 - Universal Volume Booster 版本: 1.8 作者: 醉春风制作 版权所有 (c) 2025 醉春风制作 保留所有权利。 本脚本为作者独立创作,未经作者明确授权,禁止任何形式的: 1. 复制、修改或二次开发本脚本 2. 重新发布、分发或出售本脚本 3. 移除或修改本脚本中的版权信息和作者信息 使用本脚本即表示您同意遵守上述条款。 */ (function() { 'use strict'; // 保存用户设置的音量增强倍数 let volumeMultiplier = GM_getValue('volumeMultiplier', 1.0); let isBoosterActive = GM_getValue('isBoosterActive', false); let isDragging = false; let controlsVisible = false; let hideTimeout; let lastKeyTime = 0; // 用于防止快捷键重复触发 let mediaElements = []; // 跟踪页面中的所有媒体元素 let iconVisible = GM_getValue('iconVisible', true); // 图标是否可见 let iconPosition = GM_getValue('iconPosition', { x: 20, y: 20 }); // 图标位置 let isFullscreen = false; // 跟踪全屏状态 let fullscreenChangeCount = 0; // 用于跟踪全屏变化次数 let lastVolumeChangeTime = 0; // 用于跟踪最后一次音量变化时间 let lastRightClickTime = 0; // 用于跟踪右键双击 let douyinVolumeApplied = false; // 跟踪抖音音量是否已应用 // 存储脚本实例ID,用于热重载时清理旧实例 const scriptInstanceId = Date.now().toString(36) + Math.random().toString(36).substr(2); window._volumeBoosterInstances = window._volumeBoosterInstances || []; window._volumeBoosterInstances.push(scriptInstanceId); // 存储需要清理的事件监听和定时器 let eventListeners = []; let intervalTimers = []; let mediaObserver = null; // 检测当前网站 const isYouTube = window.location.hostname.includes('youtube.com'); const isTikTok = window.location.hostname.includes('tiktok.com'); const isDouyin = window.location.hostname.includes('douyin.com'); const isKuaishou = window.location.hostname.includes('kuaishou.com') || window.location.hostname.includes('kwai.com'); const isBilibili = window.location.hostname.includes('bilibili.com'); const isXigua = window.location.hostname.includes('ixigua.com'); // 创建音量增强控制界面 function createVolumeControls() { // 添加样式 GM_addStyle(` #volume-booster-container-${scriptInstanceId} { position: fixed; top: 20px; right: 20px; background-color: rgba(0, 0, 0, 0.7); color: white; padding: 10px; border-radius: 5px; z-index: 9999999; font-family: Arial, sans-serif; transition: opacity 0.3s ease; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); user-select: none; opacity: 0; pointer-events: none; } #volume-booster-container-${scriptInstanceId}.visible { opacity: 1; pointer-events: auto; } #volume-booster-container-${scriptInstanceId}.active { border: 2px solid #4CAF50; } #volume-booster-container-${scriptInstanceId}.inactive { border: 2px solid #F44336; } #volume-booster-container-${scriptInstanceId}.fullscreen { position: fixed; top: 50px; right: 50px; z-index: 2147483647; background-color: rgba(0, 0, 0, 0.8); box-shadow: 0 0 15px rgba(0, 0, 0, 0.8); } #volume-slider-container-${scriptInstanceId} { width: 200px; margin: 10px 0; } #volume-slider-${scriptInstanceId} { width: 100%; height: 8px; -webkit-appearance: none; background: linear-gradient(to right, #4CAF50 0%, #4CAF50 ${(volumeMultiplier-1)*100/9}%, #ddd ${(volumeMultiplier-1)*100/9}%, #ddd 100%); outline: none; border-radius: 5px; cursor: pointer; } #volume-slider-${scriptInstanceId}::-webkit-slider-thumb { -webkit-appearance: none; width: 18px; height: 18px; border-radius: 50%; background: white; cursor: pointer; box-shadow: 0 0 5px rgba(0, 0, 0, 0.5); transition: all 0.2s ease; } #volume-slider-${scriptInstanceId}::-webkit-slider-thumb:hover { width: 22px; height: 22px; box-shadow: 0 0 8px rgba(0, 0, 0, 0.7); } #volume-slider-${scriptInstanceId}::-webkit-slider-thumb:active { width: 22px; height: 22px; background: #f0f0f0; } #volume-slider-${scriptInstanceId}::-moz-range-thumb { width: 18px; height: 18px; border-radius: 50%; background: white; cursor: pointer; box-shadow: 0 0 5px rgba(0, 0, 0, 0.5); border: none; transition: all 0.2s ease; } #volume-slider-${scriptInstanceId}::-moz-range-thumb:hover { width: 22px; height: 22px; box-shadow: 0 0 8px rgba(0, 0, 0, 0.7); } #volume-slider-${scriptInstanceId}::-moz-range-thumb:active { width: 22px; height: 22px; background: #f0f0f0; } #volume-slider-${scriptInstanceId}::-moz-range-progress { background-color: #4CAF50; height: 8px; border-radius: 5px; } #volume-value-${scriptInstanceId} { text-align: center; font-size: 14px; margin-top: 5px; font-weight: bold; } #volume-toggle-${scriptInstanceId} { width: 100%; padding: 8px; background-color: #4CAF50; color: white; border: none; border-radius: 3px; cursor: pointer; font-size: 14px; margin-top: 5px; transition: background-color 0.2s ease, transform 0.1s ease; } #volume-toggle-${scriptInstanceId}:hover { background-color: #45a049; } #volume-toggle-${scriptInstanceId}:active { transform: scale(0.98); } #volume-toggle-${scriptInstanceId}.inactive { background-color: #F44336; } #volume-toggle-${scriptInstanceId}.inactive:hover { background-color: #e53935; } .volume-booster-title-${scriptInstanceId} { font-size: 14px; text-align: center; margin-bottom: 5px; font-weight: bold; } .volume-booster-shortcut-${scriptInstanceId} { font-size: 12px; text-align: center; margin-top: 5px; color: #aaa; } #volume-status-indicator-${scriptInstanceId} { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: rgba(0, 0, 0, 0.7); color: white; padding: 15px 20px; border-radius: 5px; font-size: 16px; z-index: 2147483647; opacity: 0; transition: opacity 0.3s ease; pointer-events: none; text-align: center; } #volume-status-indicator-${scriptInstanceId}.visible { opacity: 1; } #volume-booster-float-button-${scriptInstanceId} { position: fixed; width: 40px; height: 40px; background-color: rgba(0, 0, 0, 0.6); color: white; border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; z-index: 9999998; box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); font-size: 18px; font-weight: bold; opacity: 0.7; transition: opacity 0.3s ease, transform 0.2s ease; } #volume-booster-float-button-${scriptInstanceId}:hover { opacity: 1; transform: scale(1.05); } #volume-booster-float-button-${scriptInstanceId}.hidden { display: none; } #volume-booster-float-button-${scriptInstanceId}.fullscreen { z-index: 2147483646; } `); // 创建控制界面 const container = document.createElement('div'); container.id = `volume-booster-container-${scriptInstanceId}`; container.className = isBoosterActive ? 'active' : 'inactive'; if (isFullscreen) { container.classList.add('fullscreen'); } container.innerHTML = ` <div class="volume-booster-title-${scriptInstanceId}">音量增强器 - 醉春风制作</div> <div id="volume-slider-container-${scriptInstanceId}"> <input type="range" id="volume-slider-${scriptInstanceId}" min="1" max="10" step="0.1" value="${volumeMultiplier}"> <div id="volume-value-${scriptInstanceId}">增强倍数: ${volumeMultiplier.toFixed(1)}x</div> </div> <button id="volume-toggle-${scriptInstanceId}" class="${isBoosterActive ? '' : 'inactive'}">${isBoosterActive ? '已启用' : '已禁用'}</button> <div class="volume-booster-shortcut-${scriptInstanceId}">快捷键: Alt+↑/↓ Alt+s Alt+5</div> `; // 抖音平台特殊处理:将控制界面添加到顶层容器 if (isDouyin) { // 尝试找到抖音的顶层容器 const douyinContainer = document.querySelector('#root') || document.body; douyinContainer.appendChild(container); } else { document.body.appendChild(container); } // 创建状态指示器 const statusIndicator = document.createElement('div'); statusIndicator.id = `volume-status-indicator-${scriptInstanceId}`; // 抖音平台特殊处理:将状态指示器添加到顶层容器 if (isDouyin) { const douyinContainer = document.querySelector('#root') || document.body; douyinContainer.appendChild(statusIndicator); } else { document.body.appendChild(statusIndicator); } // 添加事件监听 const slider = document.getElementById(`volume-slider-${scriptInstanceId}`); const toggle = document.getElementById(`volume-toggle-${scriptInstanceId}`); // 增强滑块拖动体验 slider.addEventListener('input', function() { volumeMultiplier = parseFloat(this.value); document.getElementById(`volume-value-${scriptInstanceId}`).textContent = `增强倍数: ${volumeMultiplier.toFixed(1)}x`; this.style.background = `linear-gradient(to right, #4CAF50 0%, #4CAF50 ${(volumeMultiplier-1)*100/9}%, #ddd ${(volumeMultiplier-1)*100/9}%, #ddd 100%)`; // 保存设置 GM_setValue('volumeMultiplier', volumeMultiplier); // 记录最后一次音量变化时间 lastVolumeChangeTime = Date.now(); // 立即应用音量增强 applyVolumeBoost(); // 抖音平台特殊处理:强制更新所有视频元素的音量 if (isDouyin) { forceUpdateDouyinVolume(); } }); // 滑块拖动开始 slider.addEventListener('mousedown', function() { isDragging = true; clearTimeout(hideTimeout); }); // 滑块拖动结束 document.addEventListener('mouseup', function() { if (isDragging) { isDragging = false; // 设置隐藏超时 hideTimeout = setTimeout(() => { hideControls(); }, 3000); // 抖音平台特殊处理:强制更新所有视频元素的音量 if (isDouyin && isBoosterActive) { forceUpdateDouyinVolume(); } } }); toggle.addEventListener('click', function() { toggleBooster(); // 记录最后一次音量变化时间 lastVolumeChangeTime = Date.now(); // 抖音平台特殊处理:强制更新所有视频元素的音量 if (isDouyin) { forceUpdateDouyinVolume(); } }); // 鼠标悬停显示控制界面 container.addEventListener('mouseenter', function() { clearTimeout(hideTimeout); }); container.addEventListener('mouseleave', function() { if (!isDragging) { hideTimeout = setTimeout(() => { hideControls(); }, 3000); } }); return container; } // 显示状态消息 function showStatusMessage(message) { const statusIndicator = document.getElementById(`volume-status-indicator-${scriptInstanceId}`); if (!statusIndicator) return; statusIndicator.textContent = message; statusIndicator.classList.add('visible'); setTimeout(() => { statusIndicator.classList.remove('visible'); }, 1500); } // 显示控制界面 function showControls() { clearTimeout(hideTimeout); if (!document.getElementById(`volume-booster-container-${scriptInstanceId}`)) { createVolumeControls(); } const container = document.getElementById(`volume-booster-container-${scriptInstanceId}`); if (!container) { // 如果容器不存在,重新创建 createVolumeControls(); return showControls(); // 递归调用以显示新创建的控制界面 } container.classList.add('visible'); if (isFullscreen) { container.classList.add('fullscreen'); } else { container.classList.remove('fullscreen'); } controlsVisible = true; // 记录最后一次音量变化时间 lastVolumeChangeTime = Date.now(); hideTimeout = setTimeout(() => { hideControls(); }, 3000); } // 隐藏控制界面 function hideControls() { if (!isDragging) { const container = document.getElementById(`volume-booster-container-${scriptInstanceId}`); if (container) { container.classList.remove('visible'); controlsVisible = false; } } } // 检测全屏状态变化 function setupFullscreenDetection() { // 多种全屏API的兼容性处理 const fullscreenChangeEvents = [ 'fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange', 'MSFullscreenChange' ]; fullscreenChangeEvents.forEach(eventName => { document.addEventListener(eventName, handleFullscreenChange); eventListeners.push({ type: eventName, handler: handleFullscreenChange, target: document }); }); // 定期检查全屏状态(备用方法,处理某些平台不触发事件的情况) const fullscreenCheckInterval = setInterval(checkFullscreenState, 500); intervalTimers.push(fullscreenCheckInterval); // 抖音平台特殊处理:额外的全屏检测 if (isDouyin) { const douyinFullscreenCheckInterval = setInterval(checkDouyinFullscreenState, 300); intervalTimers.push(douyinFullscreenCheckInterval); } } // 抖音平台特殊处理:检查抖音全屏状态 function checkDouyinFullscreenState() { // 检查抖音特有的全屏元素 const douyinFullscreenElements = document.querySelectorAll('.fullscreen-container, .fullscreen-mode, [class*="fullscreen"]'); const wasFullscreen = isFullscreen; if (douyinFullscreenElements.length > 0) { isFullscreen = true; } else { // 检查视频尺寸 const videos = document.querySelectorAll('video'); for (const video of videos) { const videoRect = video.getBoundingClientRect(); if ( videoRect.width > window.innerWidth * 0.9 && videoRect.height > window.innerHeight * 0.9 ) { isFullscreen = true; break; } } } // 如果全屏状态发生变化 if (wasFullscreen !== isFullscreen) { handleFullscreenChange(); } // 在全屏状态下,检查是否需要显示控制界面 if (isFullscreen) { // 如果最近有音量变化且控制界面不可见,则显示控制界面 const now = Date.now(); if (now - lastVolumeChangeTime < 500 && !controlsVisible) { showControls(); } } } // 处理全屏状态变化 function handleFullscreenChange() { const wasFullscreen = isFullscreen; updateFullscreenState(); // 如果全屏状态发生变化 if (wasFullscreen !== isFullscreen) { fullscreenChangeCount++; // 全屏时显示控制界面 if (isFullscreen) { showControls(); // 更新浮动按钮状态 const floatButton = document.getElementById(`volume-booster-float-button-${scriptInstanceId}`); if (floatButton) { floatButton.classList.add('fullscreen'); } } else { // 退出全屏时,如果控制界面可见,更新其样式 const container = document.getElementById(`volume-booster-container-${scriptInstanceId}`); if (container && container.classList.contains('visible')) { container.classList.remove('fullscreen'); } // 更新浮动按钮状态 const floatButton = document.getElementById(`volume-booster-float-button-${scriptInstanceId}`); if (floatButton) { floatButton.classList.remove('fullscreen'); } } } } // 更新全屏状态 function updateFullscreenState() { // 检查多种全屏API isFullscreen = !!( document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement ); // 备用检测方法:检查视频元素是否处于全屏状态 if (!isFullscreen) { const videos = document.querySelectorAll('video'); for (const video of videos) { // 检查视频尺寸是否接近屏幕尺寸 const videoRect = video.getBoundingClientRect(); if ( videoRect.width > window.innerWidth * 0.9 && videoRect.height > window.innerHeight * 0.9 ) { isFullscreen = true; break; } } } // 抖音平台特殊处理:检查抖音特有的全屏元素 if (!isFullscreen && isDouyin) { const douyinFullscreenElements = document.querySelectorAll('.fullscreen-container, .fullscreen-mode, [class*="fullscreen"]'); if (douyinFullscreenElements.length > 0) { isFullscreen = true; } } } // 定期检查全屏状态(备用方法) function checkFullscreenState() { const wasFullscreen = isFullscreen; updateFullscreenState(); // 如果全屏状态发生变化 if (wasFullscreen !== isFullscreen) { handleFullscreenChange(); } // 在全屏状态下,检查是否需要显示控制界面 if (isFullscreen) { // 如果最近有音量变化且控制界面不可见,则显示控制界面 const now = Date.now(); if (now - lastVolumeChangeTime < 500 && !controlsVisible) { showControls(); } } } // 应用音量增强 function applyVolumeBoost() { // 获取所有媒体元素 mediaElements = [...document.querySelectorAll('video, audio')]; mediaElements.forEach(media => { // 保存原始音量 if (media.dataset.originalVolume === undefined) { media.dataset.originalVolume = media.volume; } // 应用或恢复音量 if (isBoosterActive) { // 使用 AudioContext 增强音量 if (isDouyin) { // 抖音特殊处理:使用直接音量调整方法 setupDouyinVolumeBoost(media); } else { setupAudioBooster(media); } } else { // 恢复原始音量 if (media.dataset.originalVolume !== undefined) { media.volume = parseFloat(media.dataset.originalVolume); } // 断开音频处理节点 if (media.boosterSource) { try { media.boosterSource.disconnect(); media.boosterGain.disconnect(); media.boosterSource = null; media.boosterGain = null; media.boosterContext = null; } catch (e) { console.log('断开音频节点失败:', e); } } } }); } // 抖音平台特殊处理:强制更新所有视频元素的音量 function forceUpdateDouyinVolume() { const videos = document.querySelectorAll('video'); videos.forEach(video => { if (isBoosterActive) { // 强制应用音量增强 const originalVolume = parseFloat(video.dataset.originalVolume) || 0.5; // 使用直接设置方法 try { // 先设置为不同的值,再设置为目标值,确保触发更新 video.volume = Math.min(1.0, originalVolume * 0.99); setTimeout(() => { video.volume = Math.min(1.0, originalVolume * volumeMultiplier); }, 10); } catch (e) { console.log('抖音强制更新音量失败:', e); } // 尝试使用播放器API try { if (video.setVolume) { video.setVolume(Math.min(1.0, originalVolume * volumeMultiplier)); } } catch (e) { console.log('抖音播放器API调用失败:', e); } } else { // 恢复原始音量 if (video.dataset.originalVolume !== undefined) { video.volume = parseFloat(video.dataset.originalVolume); } } }); // 标记抖音音量已应用 douyinVolumeApplied = true; } // 抖音平台特殊处理 function setupDouyinVolumeBoost(mediaElement) { // 清除之前可能存在的音频处理节点 if (mediaElement.boosterSource) { try { mediaElement.boosterSource.disconnect(); mediaElement.boosterGain.disconnect(); mediaElement.boosterSource = null; mediaElement.boosterGain = null; mediaElement.boosterContext = null; } catch (e) { console.log('断开抖音音频节点失败:', e); } } // 对抖音使用直接音量调整方法 try { const originalVolume = parseFloat(mediaElement.dataset.originalVolume) || 0.5; // 确保不超过1.0 mediaElement.volume = Math.min(1.0, originalVolume * volumeMultiplier); // 监听音量变化,防止被平台重置 if (!mediaElement._volumeWatcherSet) { // 保存原始的音量设置方法 if (!mediaElement._originalSetVolume && mediaElement.setVolume) { mediaElement._originalSetVolume = mediaElement.setVolume; // 重写setVolume方法 mediaElement.setVolume = function(val) { // 保存原始音量 this.dataset.originalVolume = val; // 如果增强器激活,应用增强 if (isBoosterActive) { this._originalSetVolume.call(this, Math.min(1.0, val * volumeMultiplier)); } else { this._originalSetVolume.call(this, val); } }; } // 重写volume属性 const volumeDescriptor = Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, 'volume'); if (volumeDescriptor) { const originalSetter = volumeDescriptor.set; Object.defineProperty(mediaElement, 'volume', { get: function() { return volumeDescriptor.get.call(this); }, set: function(val) { // 如果是我们自己设置的值,直接通过 if (this._isSettingVolume) { originalSetter.call(this, val); return; } // 如果是外部设置的值,记录为原始音量 this.dataset.originalVolume = val; // 如果增强器激活,应用增强 if (isBoosterActive) { this._isSettingVolume = true; originalSetter.call(this, Math.min(1.0, val * volumeMultiplier)); this._isSettingVolume = false; } else { originalSetter.call(this, val); } }, configurable: true }); mediaElement._volumeWatcherSet = true; } } // 应用音量 mediaElement._isSettingVolume = true; mediaElement.volume = Math.min(1.0, originalVolume * volumeMultiplier); mediaElement._isSettingVolume = false; // 尝试使用播放器API if (mediaElement.setVolume) { mediaElement.setVolume(Math.min(1.0, originalVolume * volumeMultiplier)); } } catch (err) { console.log('抖音音量调整失败:', err); // 备用方法:尝试使用AudioContext try { setupAudioBooster(mediaElement); } catch (e) { console.log('抖音备用音量调整失败:', e); } } } // 使用 AudioContext 设置音量增强 function setupAudioBooster(mediaElement) { // 如果已经有音频上下文,先清理 if (mediaElement.boosterContext) { try { mediaElement.boosterSource.disconnect(); mediaElement.boosterGain.disconnect(); mediaElement.boosterSource = null; mediaElement.boosterGain = null; mediaElement.boosterContext = null; } catch (e) { console.log('重置音频节点失败:', e); } } // 创建新的音频处理节点 try { const AudioContext = window.AudioContext || window.webkitAudioContext; const context = new AudioContext(); const source = context.createMediaElementSource(mediaElement); const gainNode = context.createGain(); source.connect(gainNode); gainNode.connect(context.destination); mediaElement.boosterContext = context; mediaElement.boosterSource = source; mediaElement.boosterGain = gainNode; // 设置增益值 gainNode.gain.value = volumeMultiplier; } catch (e) { console.log('创建音频处理节点失败:', e); // 备用方案:直接修改音量属性 try { const originalVolume = parseFloat(mediaElement.dataset.originalVolume) || 0.5; // 确保不超过1.0 mediaElement.volume = Math.min(1.0, originalVolume * volumeMultiplier); } catch (err) { console.log('备用音量调整失败:', err); } } } // 增加音量 function increaseVolume() { // 如果未启用,则启用 if (!isBoosterActive) { enableBooster(); } // 增加音量倍数 volumeMultiplier = Math.min(10, volumeMultiplier + 0.1); GM_setValue('volumeMultiplier', volumeMultiplier); // 更新滑块 if (document.getElementById(`volume-slider-${scriptInstanceId}`)) { document.getElementById(`volume-slider-${scriptInstanceId}`).value = volumeMultiplier; document.getElementById(`volume-value-${scriptInstanceId}`).textContent = `增强倍数: ${volumeMultiplier.toFixed(1)}x`; document.getElementById(`volume-slider-${scriptInstanceId}`).style.background = `linear-gradient(to right, #4CAF50 0%, #4CAF50 ${(volumeMultiplier-1)*100/9}%, #ddd ${(volumeMultiplier-1)*100/9}%, #ddd 100%)`; } // 记录最后一次音量变化时间 lastVolumeChangeTime = Date.now(); applyVolumeBoost(); showControls(); // 抖音平台特殊处理:强制更新所有视频元素的音量 if (isDouyin) { forceUpdateDouyinVolume(); } // 显示状态提示 showStatusMessage(`音量增强: ${volumeMultiplier.toFixed(1)}x`); } // 减少音量 function decreaseVolume() { // 减少音量倍数 volumeMultiplier = Math.max(1, volumeMultiplier - 0.1); GM_setValue('volumeMultiplier', volumeMultiplier); // 更新滑块 if (document.getElementById(`volume-slider-${scriptInstanceId}`)) { document.getElementById(`volume-slider-${scriptInstanceId}`).value = volumeMultiplier; document.getElementById(`volume-value-${scriptInstanceId}`).textContent = `增强倍数: ${volumeMultiplier.toFixed(1)}x`; document.getElementById(`volume-slider-${scriptInstanceId}`).style.background = `linear-gradient(to right, #4CAF50 0%, #4CAF50 ${(volumeMultiplier-1)*100/9}%, #ddd ${(volumeMultiplier-1)*100/9}%, #ddd 100%)`; } // 记录最后一次音量变化时间 lastVolumeChangeTime = Date.now(); applyVolumeBoost(); showControls(); // 抖音平台特殊处理:强制更新所有视频元素的音量 if (isDouyin) { forceUpdateDouyinVolume(); } // 显示状态提示 showStatusMessage(`音量增强: ${volumeMultiplier.toFixed(1)}x`); } // 启用音量增强器 function enableBooster() { isBoosterActive = true; GM_setValue('isBoosterActive', true); if (document.getElementById(`volume-toggle-${scriptInstanceId}`)) { document.getElementById(`volume-toggle-${scriptInstanceId}`).textContent = '已启用'; document.getElementById(`volume-toggle-${scriptInstanceId}`).className = ''; document.getElementById(`volume-booster-container-${scriptInstanceId}`).className = isFullscreen ? 'visible active fullscreen' : 'visible active'; } applyVolumeBoost(); // 抖音平台特殊处理:强制更新所有视频元素的音量 if (isDouyin) { forceUpdateDouyinVolume(); } showStatusMessage('音量增强已启用'); } // 禁用音量增强器 function disableBooster() { isBoosterActive = false; GM_setValue('isBoosterActive', false); if (document.getElementById(`volume-toggle-${scriptInstanceId}`)) { document.getElementById(`volume-toggle-${scriptInstanceId}`).textContent = '已禁用'; document.getElementById(`volume-toggle-${scriptInstanceId}`).className = 'inactive'; document.getElementById(`volume-booster-container-${scriptInstanceId}`).className = isFullscreen ? 'visible inactive fullscreen' : 'visible inactive'; } applyVolumeBoost(); // 这会恢复原始音量 // 抖音平台特殊处理:强制更新所有视频元素的音量 if (isDouyin) { forceUpdateDouyinVolume(); } showStatusMessage('音量增强已禁用'); } // 切换音量增强器状态 function toggleBooster() { if (isBoosterActive) { disableBooster(); } else { enableBooster(); } } // 切换控制面板显示状态 function toggleControlPanel() { if (controlsVisible) { hideControls(); } else { showControls(); } } // 显示悬浮图标 function showFloatingIcon() { const floatButton = document.getElementById(`volume-booster-float-button-${scriptInstanceId}`); if (floatButton) { floatButton.classList.remove('hidden'); iconVisible = true; GM_setValue('iconVisible', true); showStatusMessage('图标已显示'); } else { // 如果图标不存在,创建它 addFloatingButton(); iconVisible = true; GM_setValue('iconVisible', true); showStatusMessage('图标已显示'); } } // 隐藏悬浮图标 function hideFloatingIcon() { const floatButton = document.getElementById(`volume-booster-float-button-${scriptInstanceId}`); if (floatButton) { floatButton.classList.add('hidden'); iconVisible = false; GM_setValue('iconVisible', false); showStatusMessage('图标已隐藏,双击右键可显示'); } } // 清理脚本实例 function cleanupScriptInstance() { // 清理UI元素 const elementsToRemove = [ document.getElementById(`volume-booster-container-${scriptInstanceId}`), document.getElementById(`volume-status-indicator-${scriptInstanceId}`), document.getElementById(`volume-booster-float-button-${scriptInstanceId}`) ]; elementsToRemove.forEach(element => { if (element && element.parentNode) { element.parentNode.removeChild(element); } }); // 清理事件监听 eventListeners.forEach(listener => { if (listener.target) { listener.target.removeEventListener(listener.type, listener.handler, listener.options); } else { document.removeEventListener(listener.type, listener.handler, listener.options); } }); // 清理定时器 intervalTimers.forEach(timer => { clearInterval(timer); }); // 断开媒体观察器 if (mediaObserver) { mediaObserver.disconnect(); } // 恢复媒体元素原始音量 mediaElements.forEach(media => { if (media.dataset.originalVolume !== undefined) { try { media.volume = parseFloat(media.dataset.originalVolume); // 断开音频处理节点 if (media.boosterSource) { media.boosterSource.disconnect(); media.boosterGain.disconnect(); media.boosterSource = null; media.boosterGain = null; media.boosterContext = null; } } catch (e) { console.log('恢复音量失败:', e); } } }); } // 热重载脚本 function hotReloadScript() { // 显示状态提示 showStatusMessage('正在重新加载脚本...'); // 保存当前状态 const currentState = { volumeMultiplier: volumeMultiplier, isBoosterActive: isBoosterActive, iconVisible: iconVisible, iconPosition: iconPosition }; // 将状态存储到临时变量 window._volumeBoosterTempState = currentState; // 清理旧的脚本实例 const oldInstances = window._volumeBoosterInstances || []; oldInstances.forEach(instanceId => { if (instanceId !== scriptInstanceId) { // 移除旧实例的UI元素 const elementsToRemove = [ document.getElementById(`volume-booster-container-${instanceId}`), document.getElementById(`volume-status-indicator-${instanceId}`), document.getElementById(`volume-booster-float-button-${instanceId}`) ]; elementsToRemove.forEach(element => { if (element && element.parentNode) { element.parentNode.removeChild(element); } }); } }); // 清理当前实例 cleanupScriptInstance(); // 重置实例列表,只保留当前实例 window._volumeBoosterInstances = [scriptInstanceId]; // 重新初始化脚本 setTimeout(() => { // 恢复之前保存的状态 if (window._volumeBoosterTempState) { volumeMultiplier = window._volumeBoosterTempState.volumeMultiplier; isBoosterActive = window._volumeBoosterTempState.isBoosterActive; iconVisible = window._volumeBoosterTempState.iconVisible; iconPosition = window._volumeBoosterTempState.iconPosition; // 保存到GM存储 GM_setValue('volumeMultiplier', volumeMultiplier); GM_setValue('isBoosterActive', isBoosterActive); GM_setValue('iconVisible', iconVisible); GM_setValue('iconPosition', iconPosition); // 清理临时状态 delete window._volumeBoosterTempState; } initializeVolumeBooster(); showStatusMessage('脚本已重新加载'); }, 100); } // 增强的快捷键检测函数 function isUpArrowWithAlt(e) { // 多重检测方法确保兼容性 return e.altKey && ( e.keyCode === 38 || e.which === 38 || e.code === 'ArrowUp' || e.key === 'ArrowUp' || e.key === 'Up' || e.key === '↑' ); } function isDownArrowWithAlt(e) { return e.altKey && ( e.keyCode === 40 || e.which === 40 || e.code === 'ArrowDown' || e.key === 'ArrowDown' || e.key === 'Down' || e.key === '↓' ); } function isSKeyWithAlt(e) { return e.altKey && ( e.keyCode === 83 || e.which === 83 || e.code === 'KeyS' || e.key === 's' || e.key === 'S' ); } function is5KeyWithAlt(e) { return e.altKey && ( e.keyCode === 53 || e.which === 53 || e.code === 'Digit5' || e.key === '5' ); } // 设置键盘监听 function setupKeyboardListeners() { // 主要监听方法 - keydown const keydownHandler = function(e) { const now = Date.now(); if (now - lastKeyTime < 200) return; if (isUpArrowWithAlt(e)) { e.preventDefault(); e.stopPropagation(); lastKeyTime = now; increaseVolume(); return false; } if (isDownArrowWithAlt(e)) { e.preventDefault(); e.stopPropagation(); lastKeyTime = now; decreaseVolume(); return false; } if (isSKeyWithAlt(e)) { e.preventDefault(); e.stopPropagation(); lastKeyTime = now; toggleBooster(); return false; } if (is5KeyWithAlt(e)) { e.preventDefault(); e.stopPropagation(); lastKeyTime = now; hotReloadScript(); return false; } // 检测Alt键 + V键 (显示/隐藏控制面板) if (e.altKey && (e.keyCode === 86 || e.which === 86 || e.code === 'KeyV' || e.key === 'v' || e.key === 'V')) { e.preventDefault(); e.stopPropagation(); toggleControlPanel(); return false; } }; document.addEventListener('keydown', keydownHandler, true); eventListeners.push({ type: 'keydown', handler: keydownHandler, options: true }); // 备用监听方法 - keypress (用于某些浏览器) const keypressHandler = function(e) { const now = Date.now(); if (now - lastKeyTime < 200) return; if (isUpArrowWithAlt(e) || isDownArrowWithAlt(e) || isSKeyWithAlt(e) || is5KeyWithAlt(e)) { e.preventDefault(); e.stopPropagation(); return false; } }; document.addEventListener('keypress', keypressHandler, true); eventListeners.push({ type: 'keypress', handler: keypressHandler, options: true }); // 监听右键双击事件 const contextMenuHandler = function(e) { const now = Date.now(); if (now - lastRightClickTime < 500) { // 双击右键,显示悬浮图标 e.preventDefault(); showFloatingIcon(); lastRightClickTime = 0; // 重置,防止三击触发 } else { lastRightClickTime = now; } }; document.addEventListener('contextmenu', contextMenuHandler, true); eventListeners.push({ type: 'contextmenu', handler: contextMenuHandler, options: true }); } // 监听新添加的媒体元素 function setupMediaObserver() { mediaObserver = new MutationObserver(mutations => { let mediaAdded = false; mutations.forEach(mutation => { mutation.addedNodes.forEach(node => { if (node.nodeName === 'VIDEO' || node.nodeName === 'AUDIO') { mediaAdded = true; } else if (node.nodeType === 1) { const mediaElements = node.querySelectorAll('video, audio'); if (mediaElements.length > 0) { mediaAdded = true; } } }); }); if (mediaAdded && isBoosterActive) { applyVolumeBoost(); // 抖音平台特殊处理:强制更新所有视频元素的音量 if (isDouyin) { forceUpdateDouyinVolume(); } } }); // 开始观察DOM变化 if (document.body) { mediaObserver.observe(document.body, { childList: true, subtree: true }); } return mediaObserver; } // 添加可拖动的悬浮音频图标 function addFloatingButton() { const floatButton = document.createElement('div'); floatButton.id = `volume-booster-float-button-${scriptInstanceId}`; floatButton.textContent = '🔊'; floatButton.title = '音量增强器 - 醉春风制作 (Alt+↑/↓ Alt+s Alt+5)'; // 设置初始位置 floatButton.style.left = `${iconPosition.x}px`; floatButton.style.top = `${iconPosition.y}px`; // 如果图标应该隐藏,添加隐藏类 if (!iconVisible) { floatButton.classList.add('hidden'); } // 如果当前是全屏状态,添加全屏类 if (isFullscreen) { floatButton.classList.add('fullscreen'); } // 点击显示控制面板 floatButton.addEventListener('click', function(e) { if (!isDragging) { showControls(); } }); // 右键点击隐藏图标 floatButton.addEventListener('contextmenu', function(e) { e.preventDefault(); hideFloatingIcon(); }); // 实现拖动功能 let startX, startY, startLeft, startTop; floatButton.addEventListener('mousedown', function(e) { // 只处理左键点击的拖动 if (e.button !== 0) return; e.preventDefault(); isDragging = true; // 记录初始位置 startX = e.clientX; startY = e.clientY; startLeft = parseInt(window.getComputedStyle(floatButton).left); startTop = parseInt(window.getComputedStyle(floatButton).top); // 添加鼠标移动和松开事件 document.addEventListener('mousemove', dragMove); document.addEventListener('mouseup', dragEnd); }); function dragMove(e) { if (!isDragging) return; // 计算新位置 const newLeft = startLeft + (e.clientX - startX); const newTop = startTop + (e.clientY - startY); // 限制在窗口内 const maxLeft = window.innerWidth - floatButton.offsetWidth; const maxTop = window.innerHeight - floatButton.offsetHeight; floatButton.style.left = `${Math.max(0, Math.min(maxLeft, newLeft))}px`; floatButton.style.top = `${Math.max(0, Math.min(maxTop, newTop))}px`; } function dragEnd() { if (!isDragging) return; isDragging = false; // 保存新位置 iconPosition = { x: parseInt(floatButton.style.left), y: parseInt(floatButton.style.top) }; GM_setValue('iconPosition', iconPosition); // 移除事件监听 document.removeEventListener('mousemove', dragMove); document.removeEventListener('mouseup', dragEnd); } // 抖音平台特殊处理:将浮动按钮添加到顶层容器 if (isDouyin) { const douyinContainer = document.querySelector('#root') || document.body; douyinContainer.appendChild(floatButton); } else { document.body.appendChild(floatButton); } return floatButton; } // 特殊网站兼容性处理 function handleSpecialWebsites() { // YouTube特殊处理 if (isYouTube) { // 监听YouTube播放器变化 const ytInterval = setInterval(() => { const ytPlayer = document.querySelector('video.html5-main-video'); if (ytPlayer && isBoosterActive && !ytPlayer.boosterContext) { setupAudioBooster(ytPlayer); } // 检查是否处于全屏状态 updateFullscreenState(); }, 1000); intervalTimers.push(ytInterval); } // 抖音特殊处理 if (isDouyin) { // 监听抖音视频变化 const douyinInterval = setInterval(() => { const douyinVideos = document.querySelectorAll('video'); if (douyinVideos.length > 0 && isBoosterActive) { douyinVideos.forEach(video => { setupDouyinVolumeBoost(video); }); // 强制更新所有视频元素的音量 forceUpdateDouyinVolume(); } // 检查是否处于全屏状态 updateFullscreenState(); // 确保控制界面在全屏状态下可见 if (isFullscreen && Date.now() - lastVolumeChangeTime < 500 && !controlsVisible) { showControls(); } }, 500); intervalTimers.push(douyinInterval); // 额外的抖音全屏检测 const douyinFullscreenInterval = setInterval(() => { checkDouyinFullscreenState(); }, 300); intervalTimers.push(douyinFullscreenInterval); } // TikTok特殊处理 if (isTikTok) { // 监听TikTok视频变化 const ttInterval = setInterval(() => { const tikTokVideos = document.querySelectorAll('video'); if (tikTokVideos.length > 0 && isBoosterActive) { tikTokVideos.forEach(video => { if (!video.boosterContext) { setupAudioBooster(video); } }); } // 检查是否处于全屏状态 updateFullscreenState(); }, 1000); intervalTimers.push(ttInterval); } // 快手特殊处理 if (isKuaishou) { // 监听快手视频变化 const ksInterval = setInterval(() => { const kuaishouVideos = document.querySelectorAll('video'); if (kuaishouVideos.length > 0 && isBoosterActive) { kuaishouVideos.forEach(video => { if (!video.boosterContext) { setupAudioBooster(video); } }); } // 检查是否处于全屏状态 updateFullscreenState(); }, 1000); intervalTimers.push(ksInterval); } // B站特殊处理 if (isBilibili) { // 监听B站视频变化 const biliInterval = setInterval(() => { const biliVideos = document.querySelectorAll('video'); if (biliVideos.length > 0 && isBoosterActive) { biliVideos.forEach(video => { if (!video.boosterContext) { setupAudioBooster(video); } }); } // 检查是否处于全屏状态 updateFullscreenState(); }, 1000); intervalTimers.push(biliInterval); } // 西瓜视频特殊处理 if (isXigua) { // 监听西瓜视频变化 const xiguaInterval = setInterval(() => { const xiguaVideos = document.querySelectorAll('video'); if (xiguaVideos.length > 0 && isBoosterActive) { xiguaVideos.forEach(video => { if (!video.boosterContext) { setupAudioBooster(video); } }); } // 检查是否处于全屏状态 updateFullscreenState(); }, 1000); intervalTimers.push(xiguaInterval); } // 通用视频处理(适用于所有网站) const generalInterval = setInterval(() => { const videos = document.querySelectorAll('video'); if (videos.length > 0 && isBoosterActive) { videos.forEach(video => { if (!video.boosterContext && !isDouyin) { setupAudioBooster(video); } }); } // 检查是否有音量变化,如果在全屏状态下且最近有音量变化,显示控制界面 if (isFullscreen && Date.now() - lastVolumeChangeTime < 500 && !controlsVisible) { showControls(); } }, 1000); intervalTimers.push(generalInterval); } // 初始化音量增强器 function initializeVolumeBooster() { // 创建控制界面但不显示 createVolumeControls(); // 设置键盘监听 setupKeyboardListeners(); // 设置媒体观察器 setupMediaObserver(); // 设置全屏检测 setupFullscreenDetection(); // 添加悬浮按钮 addFloatingButton(); // 处理特殊网站兼容性 handleSpecialWebsites(); // 应用音量增强 if (isBoosterActive) { applyVolumeBoost(); // 抖音平台特殊处理:强制更新所有视频元素的音量 if (isDouyin) { forceUpdateDouyinVolume(); } } // 定期检查并应用音量增强(处理动态加载的媒体) const checkInterval = setInterval(() => { if (isBoosterActive) { applyVolumeBoost(); // 抖音平台特殊处理:强制更新所有视频元素的音量 if (isDouyin && !douyinVolumeApplied) { forceUpdateDouyinVolume(); } } }, 2000); intervalTimers.push(checkInterval); // 初始检查全屏状态 updateFullscreenState(); } // 如果页面已经加载完成,立即初始化 if (document.readyState === 'complete' || document.readyState === 'interactive') { // 延迟一点以确保DOM已准备好 setTimeout(function() { if (document.body) { initializeVolumeBooster(); } }, 100); } else { // 否则等待DOMContentLoaded事件 window.addEventListener('DOMContentLoaded', function() { setTimeout(function() { initializeVolumeBooster(); }, 100); }); } // 立即设置键盘监听,不等待页面加载 setupKeyboardListeners(); // 立即初始化,不等待页面加载完成 // 这样可以更早地捕获键盘事件和处理媒体元素 setTimeout(() => { if (document.body) { // 创建控制界面但不显示 createVolumeControls(); // 应用音量增强 applyVolumeBoost(); // 设置媒体观察器 setupMediaObserver(); // 设置全屏检测 setupFullscreenDetection(); } }, 500); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址