// ==UserScript== // @name b站视频音量调节触控板翻转 // @namespace http://zhangmaimai.com/ // @version 1.0 // @description 优化b站视频音量调节在触控板上的体验,触控板上的上下滑动是与鼠标滚轮翻转的,使用此脚本后当你在b站视频全屏时向下滑动将减少音量(默认为增大) // @author maxchang3 // @match https://www.bilibili.com/video/* // @match https://www.bilibili.com/bangumi/play/* // @icon https://www.bilibili.com/favicon.ico // @grant none // @license https://github.com/996icu/996.ICU/blob/master/LICENSE // @downloadURL none // ==/UserScript== (function () { 'use strict'; let hintTimer = undefined const initHint = () => { const hintCode = `
` if (document.querySelector('.bpx-player-volume-hint')) return document.querySelector('.bpx-player-video-area').insertAdjacentHTML('beforeend', hintCode) } const showHint = (volume) => { window.clearTimeout(hintTimer) const volHint = document.querySelector('.bpx-player-volume-hint') const volText = volHint.querySelector('.bpx-player-volume-hint-text') const volIconArea = volHint.querySelector('.bpx-player-volume-hint-icon') const volIcons = volIconArea.querySelectorAll('.bpx-common-svg-icon') if (volume == 0) { volText.innerText = '静音' volIcons[0].style.display = 'none' volIcons[1].style.display = 'inline-flex' } else { volIcons[0].style.display = 'inline-flex' volIcons[1].style.display = 'none' volText.innerText = `${Math.ceil(volume * 100)}%` } volHint.style.display = '' volHint.style.opacity = 1 hintTimer = window.setTimeout((function () { const animation = volHint.animate({ opacity: 0 }, 300); animation.onfinish = function () { animation.cancel() volHint.style.display = 'none' volHint.style.opacity = 0 } }), 1e3) } const isFullScreen = () => { return !!( document.fullscreen || document.mozFullScreen || document.webkitIsFullScreen || document.webkitFullScreen || document.msFullScreen ); } const handler = (e) => { // 同时接管触控板与鼠标滚轮出发下的提醒,从而避免提醒重复显示的情况,因此对于鼠标触发的值需要额外放大魔数以计算增长音量与wheelDeltaY的关系。 // 触控板下wheelDeltaY更为精准因此明显小于鼠标,这里以100为阈值。经过测试(罗技MX Anywhere2s下)鼠标最低约在240或360左右,这里为了防止硬件差异选择100。 // 灵感来自:https://stackoverflow.com/questions/10744645/detect-touchpad-vs-mouse-in-javascript 在这里不需要过于精准的判断,基本够用。 let isTrackpad = (e.wheelDeltaY && Math.abs(e.wheelDeltaY) < 100); let isFullscreen = (Array.from(document.querySelector('body').classList)).includes("player-fullscreen-fix") || isFullScreen(); if (!(isFullscreen)) return false //非全屏下不接管事件 //阻止默认事件 e.stopImmediatePropagation(); e.stopPropagation(); let flag = -1 // Trackpad 值转为 1 与 -1 ,在触控板与鼠标情况下进行加减的逆转。 let MAGIC_NUMBER = 36000 if (isTrackpad && isFullscreen) { flag = 1; MAGIC_NUMBER /= 72; } let newVolume = window.player.getVolume() - flag * e.wheelDeltaY / MAGIC_NUMBER; newVolume = (newVolume < 1) ? Math.max(newVolume, 0) : 1 // 小于0取0,大于1取1 window.player.setVolume(newVolume) showHint(window.player.getVolume()) } const init = () => { initHint() document.addEventListener("DOMMouseScroll", handler, false); document.addEventListener("wheel", handler, false); } window.onload = init })();