// ==UserScript== // @name 自定义哔哩哔哩视频播放速度,记住播放速度 // @namespace http://tampermonkey.net/ // @version 1.0.3 // @description 可以使用按键 z(恢复1倍速)、x(减0.1倍速)、c(加0.1倍速)、s(记住或忘记播放速度), 跳过充电 // @author felix // @icon chrome://favicon/http://www.bilibili.com/ // @match https://www.bilibili.com/video/* // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @downloadURL none // ==/UserScript== (function () { 'use strict'; // console.log(`[${GM_info.script.name}]: 开始运行`); // ===================================================配置区===================================================================================== var STORAGE_KEY = { BILIBILI_VIDEO_SPEED_SIWTCH: "bilibili_video_speed_switch", BILIBILI_VIDEO_SPEED: "bilibili_video_speed" }; var SETTING = { STEP_SIZE: 0.1, MAX_SPEED: 5, MIN_SPEED: 0.1, REMEMBER_SPEED_MENU_ID: null, }; var DOM_NAME = { SPEED: ".bilibili-player-video-btn-speed-name", VIDEO: "bwp-video", VIDEO_2: "video", JUMP_BUTTON: ".bilibili-player-electric-panel-jump", CUSTOMER_TOAST: ".bilibili-player-volumeHint.felix", CUSTOMER_TOAST_SUB_DOM: ".bilibili-player-volumeHint.felix .bilibili-player-volumeHint-text", } var CONSTANT_DATA = { REMOVE_SPEED_TOAST_INTERVAL: null } // ===================================================加载区===================================================================================== setTimeout(loading, 3000); function loading() { addToast(); loadSpeed(); addInterval(); } function addInterval() { addSpeedInterval(); addJumpElectricInterval(); } // 每3秒检测一次播放速度 function addSpeedInterval() { return setInterval(() => { var videoSpeed = getVideoSpeed(); var videoSpeedTextNumber = getVideoSpeedTextNumber(); if (Number(videoSpeed) !== videoSpeedTextNumber) { console.log("change speed", videoSpeedTextNumber) changeSpeed(videoSpeedTextNumber, false); } }, 3000); } // 跳过充电 function addJumpElectricInterval() { return setInterval(() => { if ($(DOM_NAME.JUMP_BUTTON).length > 0) { $(DOM_NAME.JUMP_BUTTON).trigger('click') } }, 500) } function loadSpeed() { var speedSwitch = localStorage.getItem(STORAGE_KEY.BILIBILI_VIDEO_SPEED_SIWTCH) if (speedSwitch == "true") { var speed = localStorage.getItem(STORAGE_KEY.BILIBILI_VIDEO_SPEED); if (speed) { changeSpeed(speed, false); loadRemoveSpeedMenu(); } else { loadSaveSpeedMenu(); } } } // =============================================== toast ========================================================== function hasToast() { var toastDom = $(DOM_NAME.CUSTOMER_TOAST) return toastDom != null && toastDom != undefined; } function addToast() { var div = $( `
` ) $(".bilibili-player-video-wrap").append(div); } function toast(str) { $(DOM_NAME.CUSTOMER_TOAST).attr("style", '{ "opacity": 100, "display": "block" }'); $(DOM_NAME.CUSTOMER_TOAST_SUB_DOM).text(str); if (CONSTANT_DATA.REMOVE_SPEED_TOAST_INTERVAL) { clearInterval(CONSTANT_DATA.REMOVE_SPEED_TOAST_INTERVAL); } CONSTANT_DATA.REMOVE_SPEED_TOAST_INTERVAL = setInterval(() => { var opacity = $(DOM_NAME.CUSTOMER_TOAST).css("opacity") opacity = opacity - 0.05; if (opacity <= 0.7) { $(DOM_NAME.CUSTOMER_TOAST).css("opacity", 0); $(DOM_NAME.CUSTOMER_TOAST).css("dispaly", "none"); clearInterval(CONSTANT_DATA.REMOVE_SPEED_TOAST_INTERVAL); } else { $(DOM_NAME.CUSTOMER_TOAST).css("opacity", opacity); } }, 200); } // ===================================================获取控件区===================================================================================== function getVideo() { var video = document.querySelector(DOM_NAME.VIDEO) return video ? video : document.querySelector(DOM_NAME.VIDEO_2); } // ===================================================键盘监听区===================================================================================== document.onkeydown = function (e) { if (e.target.nodeName !== 'BODY') return; if (/^[zxcZXCsS]$/.test(e.key)) { if (e.key === 'z' || e.key === 'Z') changeSpeed(1, true); if (e.key === 'x' || e.key === 'X') reduceSpeed(); if (e.key === 'c' || e.key === 'C') addSpeed(); if (e.key === 's' || e.key === 'S') changeSaveSpeedSwitch(); } }; // ==================================================播放速度================================================================================= // 加载记住播放速度菜单 function loadSaveSpeedMenu() { if (SETTING.REMEMBER_SPEED_MENU_ID) { GM_unregisterMenuCommand(SETTING.REMEMBER_SPEED_MENU_ID); } SETTING.REMEMBER_SPEED_MENU_ID = GM_registerMenuCommand("记住播放速度", openSaveSpeedSwitch); } // 加载忘记播放速度菜单 function loadRemoveSpeedMenu() { if (SETTING.REMEMBER_SPEED_MENU_ID) { GM_unregisterMenuCommand(SETTING.REMEMBER_SPEED_MENU_ID); } SETTING.REMEMBER_SPEED_MENU_ID = GM_registerMenuCommand("忘记播放速度", closeSaveSpeedSwitch); } function changeSaveSpeedSwitch() { var speedSwitch = localStorage.getItem(STORAGE_KEY.BILIBILI_VIDEO_SPEED_SIWTCH); if (speedSwitch == "true") { // 当前是记住 closeSaveSpeedSwitch(); toast("已忘记"); } else { openSaveSpeedSwitch(); toast("已记住"); } } // 开启记住播放速度开关 function openSaveSpeedSwitch() { localStorage.setItem(STORAGE_KEY.BILIBILI_VIDEO_SPEED_SIWTCH, true); setSpeedToStorage(); } // 关闭记住播放速度开关 function closeSaveSpeedSwitch() { localStorage.setItem(STORAGE_KEY.BILIBILI_VIDEO_SPEED_SIWTCH, false); removeSpeedFromStorage(); } // 保存播放速度到localStorage function setSpeedToStorage() { localStorage.setItem(STORAGE_KEY.BILIBILI_VIDEO_SPEED, getVideoSpeed()); loadRemoveSpeedMenu(); } // 从localStorage中删除保存的播放速度 function removeSpeedFromStorage() { localStorage.removeItem(STORAGE_KEY.BILIBILI_VIDEO_SPEED); loadSaveSpeedMenu(); } // 获取当前播放速度 function getVideoSpeed() { return getVideo().playbackRate; } // 获取当前展示的播放速度 function getVideoSpeedTextNumber() { var speedText = $(DOM_NAME.SPEED).text() if (speedText == "倍速") { speedText = "1"; } speedText = speedText.replaceAll("x", "") return Number(speedText); } // 改变展示的播放速度文字 function changeSpeedText(playSpeed) { $(DOM_NAME.SPEED).text(playSpeed); } // 减速 function reduceSpeed(stepSize) { if (!stepSize) { stepSize = SETTING.STEP_SIZE; } var playSpeed = Number(getVideoSpeedTextNumber() - stepSize).toFixed(1); changeSpeed(playSpeed, true); } // 加速 function addSpeed(stepSize) { if (!stepSize) { stepSize = SETTING.STEP_SIZE; } var playSpeed = Number(getVideoSpeedTextNumber() + stepSize).toFixed(1); changeSpeed(playSpeed, true); } // 改变播放速度 function changeSpeed(playSpeed, showToast) { if (playSpeed && playSpeed >= SETTING.MIN_SPEED && playSpeed <= SETTING.MAX_SPEED) { doChangeSpeed(playSpeed); changeSpeedText(playSpeed); var saveSpeedswitch = localStorage.getItem(STORAGE_KEY.BILIBILI_VIDEO_SPEED_SIWTCH); if (saveSpeedswitch) { setSpeedToStorage(); } if (!hasToast()) { addToast(); } if (showToast) { toast(playSpeed); } } } // 执行调整播放速度 function doChangeSpeed(playSpeed) { getVideo().playbackRate = Number(playSpeed); } })();