Greasy Fork

Greasy Fork is available in English.

b站视频音量调节触控板翻转

优化b站视频音量调节在触控板上的体验,触控板上的上下滑动是与鼠标滚轮翻转的,使用此脚本后当你在b站视频全屏时向下滑动将减少音量(默认为增大)

当前为 2021-09-23 提交的版本,查看 最新版本

// ==UserScript==
// @name         b站视频音量调节触控板翻转
// @namespace    http://zhangmaimai.com/
// @version      0.5
// @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
// ==/UserScript==
// Hinter Codes copy and revision from //https://github.com/jeayu/bilibili-quickdo

'use strict';
const MODE_BANGUMI = 0
const MODE_VIDEO = 1

let hintTimer = null;
let volumeHint;
let mode = MODE_VIDEO
if((location.pathname).includes('/bangumi/play')){
    volumeHint = document.querySelector('.bpx-player-volume-hint');
    mode = MODE_BANGUMI
}else{
    volumeHint = document.querySelector('.bilibili-player-volumeHint');
}
function initHinter(){
    volumeHint = document.querySelector('.bilibili-player-volumeHint');
    if((volumeHint))return false;
    let hintHTML =`
     <div class="bilibili-player-volumeHint"  style="opacity: 0; display: none;transition:opacity 1s;">
            <span class="bilibili-player-volumeHint-icon">
                <i class="bilibili-player-iconfont bilibili-player-iconfont-volume icon-24soundsmall"></i>
                <i class="bilibili-player-iconfont bilibili-player-iconfont-volume-max icon-24soundlarge"></i>
                <i class="bilibili-player-iconfont bilibili-player-iconfont-volume-min icon-24soundoff"></i>
            </span>
            <span class="bilibili-player-volumeHint-text" id="custom-hint-text">1%</span>
       </div>
    `
    document.querySelector('.bilibili-player-video-wrap').insertAdjacentHTML('beforeend',hintHTML);
    volumeHint = document.querySelector('.bilibili-player-volumeHint');
}

function initHinter_bpx(){
  // 对于番剧页面单独处理
  volumeHint = document.querySelector('.bpx-player-volume-hint');
  if(volumeHint) return false;
  let hintHTML = `
    <div class="bpx-player-volume-hint" style="opacity: 0; display: none;">
                    <span class="bpx-player-volume-hint-icon"><span class="bpx-common-svg-icon">
            <svg viewBox="0 0 22 22">
                <use xlink:href="#bpx-svg-sprite-volume"></use>
            </svg>
        </span><span class="bpx-common-svg-icon" style="display: none;">
            <svg viewBox="0 0 22 22">
                <use xlink:href="#bpx-svg-sprite-volume-off"></use>
            </svg>
        </span></span>
                    <span class="bpx-player-volume-hint-text">77%</span>
     </div>
    `
   document.querySelector('.bpx-player-video-area').insertAdjacentHTML('beforeend',hintHTML);
   volumeHint = document.querySelector('.bpx-player-volume-hint');
}

function showHinter(val){
    mode?initHinter():initHinter_bpx();
    clearTimeout(hintTimer);
    volumeHint.style.opacity = 1;
    volumeHint.style.display = '';
    if(mode == MODE_VIDEO){
         document.querySelector('.bilibili-player-volumeHint-text').innerText= val + '%';
    }else{
         document.querySelector('.bpx-player-volume-hint-text').innerText= val + '%';
    }
    hintTimer = setTimeout(() => {
       volumeHint.style.opacity = 0;
       volumeHint.style.display = 'none';
    }, 500);

}

function handler(e) {
  //阻止默认事件
  e.stopImmediatePropagation();
  e.stopPropagation();
  // 同时接管触控板与鼠标滚轮出发下的提醒,从而避免提醒重复显示的情况,因此对于鼠标触发的值需要额外放大魔数以计算增长音量与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");
  let flag = -1; // Trackpad值转为1与-1,在触控板与鼠标情况下进行加减的逆转。
  let MAGIC_NUMBER = 36000;
  if(isTrackpad && isFullscreen) {flag = 1;MAGIC_NUMBER/=72; };
  let player = (document.querySelector(".bilibili-player-video")?.firstChild ) || document.querySelector('.bpx-player-video-wrap').firstChild;
  let newVolume = player.volume - flag*e.wheelDeltaY/MAGIC_NUMBER;
  newVolume = (newVolume<1)?Math.max(newVolume,0):1; // 小于0取0,大于1取1
  player.volume = newVolume;
  //修改音量条、数字
  if(mode == MODE_BANGUMI){
    // 番剧界面
    document.querySelector('.squirtle-volume-dot').style.bottom = `${54*player.volume}px`
    document.querySelector('.squirtle-volume-full').style.height = `${60-60*player.volume}px`
    document.querySelector('.squirtle-volume-num').innerText = Math.ceil(newVolume*100);
  }else{
    document.querySelector('div.bilibili-player-video-volumebar.bui.bui-slider > div > div.bui-bar-wrap > div').style.transform = `scaleY(${newVolume.toFixed(2)})`;
    document.querySelector('div.bilibili-player-video-volumebar .bui-thumb').style.transform = `translateY(${-48*player.volume}px)`;
    document.querySelector('.bilibili-player-video-volume-num').innerText = Math.ceil(newVolume*100);
  }

  //弹出提醒
  showHinter(Math.ceil(player.volume*100))
}

document.addEventListener("DOMMouseScroll", handler, false);
document.addEventListener("wheel", handler, false);