您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
B站播放器速度自定义(0.25 ~ 3), 支持快捷键(z:正常, x:减少速度, c:增加速度), 鼠标中键切换全屏等
当前为
// ==UserScript== // @name 哔哩哔哩(B站, bilibili)播放界面和部分操作优化 // @description B站播放器速度自定义(0.25 ~ 3), 支持快捷键(z:正常, x:减少速度, c:增加速度), 鼠标中键切换全屏等 // @namespace bili // @version 1.6.6 // @author vizo // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js // @include *://www.bilibili.com/video* // @include *://www.bilibili.com/bangumi* // @include *://www.bilibili.com/medialist/play* // @include https://search.bilibili.com* // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // @run-at document-end // @noframes // ==/UserScript== GM_addStyle(` html { overflow-y: scroll; } html.hideScroll { overflow: hidden; transform: translateX(-3px); } body::-webkit-scrollbar { width: 6px; } body::-webkit-scrollbar-corner, body::-webkit-scrollbar-track { background-color: #f8f8f8; } body::-webkit-scrollbar-thumb { background: #c5c5c5; } #bilibili-player { position: relative; } #spsy_msg { width: 105px; height: 42px; text-align: center; line-height: 42px; border-radius: 4px; background: rgba(255,255,255,.8); color: #222; font-size: 16px; position: absolute; top: -80px; right: 0; bottom: 0; left: 0; margin: auto; z-index: 99999; pointer-events: none; display: none; } #bl_info_xz { height: 25px; line-height: 25px; font-size: 14px; padding: 0 5px; color: #00a1d6; position: absolute; top: -25px; right: 0; z-index: 2; } .bilibili-player-video-btn-volume, .bilibili-player-video-btn-speed { opacity: 0.4; pointer-events: none; } .bilibili-player-volumeHint { display: none !important; } .so-fg5r { } .so-fg5r .inp { width: 50px; color: #666; border: 1px solid #0ad; border-radius: 2px; padding: 2px 5px; outline: none; } .so-fg5r .inp:focus { border-color: #0ad; } .so-fg5r span { color: #666; } .video-item.hide_7s { display: none !important; } `) const G = { timer1s: 0, timer2s: 0, timer3s: 0, focusChangeTime: 0, g2URL: '', } const R = { timeout(ms = 0) { return new Promise(resolve => setTimeout(resolve, ms)) }, round(val, n = 2) { return Number(`${Math.round(`${val}e${n}`)}e-${n}`) }, floor(val, n = 2) { return Number(`${Math.floor(`${val}e${n}`)}e-${n}`) }, loadEl(fnz, timeout = 30e3) { return new Promise(resolve => { const iFn = () => { let el = typeof fnz === 'function' ? fnz() : $(fnz) if (el.length) { return resolve(el) } setTimeout(iFn, 50) } iFn() setTimeout(() => { return resolve($(null)) }, timeout) }) }, watchDom(el, ...args) { if (typeof el === 'string') { el = document.querySelector(el) } let opt = args.length > 1 ? args[0] : {} let cb = args.length > 1 ? args[1] : args[0] return new MutationObserver((mutations, observer) => { cb(mutations) }).observe(el, Object.assign({ childList: true, attributes: true, characterData: true, subtree: true, }, opt)) }, async getVideoWrap() { return (await R.loadEl('#bilibiliPlayer'))[0] }, async getVideo() { return (await R.loadEl(`#${(await R.getVideoWrap()).id} video`))[0] }, async appendMsgLay() { let wp = await R.getVideoWrap() let msg = document.getElementById('spsy_msg') if (!wp.contains(msg)) { wp.insertAdjacentHTML('beforeend', `<div id="spsy_msg"></div>`) } }, async appendAxInfo() { let wp = await R.getVideoWrap() let inf = document.getElementById('bl_info_xz') if (!wp.contains(inf)) { wp.insertAdjacentHTML('beforeend', `<div id="bl_info_xz"></div>`) } }, setAxInfo() { let inf = $('#bl_info_xz') let vol = Math.trunc(R.getGMvolume() * 100) let speed = R.getGMspeed() if (inf.length) { speed = speed === 1 ? speed : `<span style="color:#f33;">${speed}</span>` inf.html(`<span>速度: ${speed} 音量: ${vol}</span>`) } }, toggleVideoFullscreen() { $('.bilibili-player-video-btn-fullscreen')[0].click() }, setGMspeed(val) { return GM_setValue('--> bl_player_speed', val) }, setGMvolume(val) { GM_setValue('--> bl_player_volume', val) }, getGMspeed() { return +GM_getValue('--> bl_player_speed') || 1 }, getGMvolume() { let vol = GM_getValue('--> bl_player_volume') return vol !== undefined ? vol : 0.5 }, // 判断是否全屏 isFullScreen() { return document.isFullScreen || document.mozIsFullScreen || document.webkitIsFullScreen }, // 显示信息 showSpMsg(msg, type = '速度') { let mp = $('#spsy_msg') clearTimeout(G.timer2s) mp.fadeIn(180) mp.text(`${type} ${msg}`) G.timer2s = setTimeout(() => { mp.fadeOut(350) }, 800) }, // 设置播放器播放速度 async setPlayerSpeed(speedVal = R.getGMspeed()) { let video = await R.getVideo() video.playbackRate = speedVal R.setGMspeed(speedVal) R.setAxInfo() }, // 设置音量 async setVolume(vol = R.getGMvolume()) { let video = await R.getVideo() video.volume = vol R.setGMvolume(vol) R.setAxInfo() }, initVideoCfg() { clearTimeout(G.timer3s) G.timer3s = setTimeout(() => { R.appendMsgLay() R.appendAxInfo() R.setPlayerSpeed() R.setVolume() }, 10) }, debounce(func, delay) { let timer = null return function() { timer && clearTimeout(timer) timer = setTimeout(() => { func.apply(this, arguments) }, delay) } }, zTimer() { R.initVideoCfg() setTimeout(R.zTimer, 2000) }, async regWpMouseEvt() { const wwp = $('#playerWrap') const wp = wwp.length ? wwp : await R.getVideoWrap() $(wp).on('mouseenter', () => { $('html').addClass('hideScroll') }) $(wp).on('mouseleave', () => { $('html').removeClass('hideScroll') }) }, watchUrlFunc() { if (G.g2URL !== location.href) { G.g2URL = location.href R.eachSearchResultAndAddHideCls() } setTimeout(R.watchUrlFunc, 500) }, judgeIsAppendSoMod() { const html = ` <div class="so-fg5r"> <input class="inp inp-s" type="text"> <span> - </span> <input class="inp inp-e" type="text"> <span>分钟</span> </div> ` $('ul.filter-type.duration').append(html) }, eachSearchResultAndAddHideCls() { const val1 = $('.inp-s').val() const val2 = $('.inp-e').val() if (!val1 || !val2) { $('.video-list > li.video-item').each((i, v) => { $(v).removeClass('hide_7s') }) return } $('.video-list > li.video-item').each((i, v) => { let tis = $(v) tis.removeClass('hide_7s') let sTime = tis.find('.so-imgTag_rb').text() let mth = sTime.match(/\d{2}(?=(\:\d{2}){2})/) let hour = mth ? mth[0] : 0 let minute = sTime.replace(/(?:\d{2}\:)?(\d{2})\:\d{2}/, '$1') let total = Number(hour) * 60 + Number(minute) if (total < Number(val1) || total > Number(val2)) { tis.closest('.video-item').addClass('hide_7s') } }) }, } // 滚轮中键点击(滚轮点击)切换全屏 $('body').on('mousedown', '#bilibili-player', function(e) { if (e.button === 1) { e.preventDefault() R.toggleVideoFullscreen() } }) // 筛选搜索结果 $('body').on('change', '.inp-s, .inp-e', function() { R.eachSearchResultAndAddHideCls() }) // ctrl和alt按下后短时间内阻止zxc $('body').on('keydown', function(e) { if (/up|down/i.test(e.key)) { e.stopPropagation() e.preventDefault() } }) // 键盘快捷键 $('body').on('keyup', async function(e) { if (e.target.nodeName !== 'BODY') return if (/^[zxc]$/.test(e.key)) { await R.timeout(100) if (Date.now() - G.focusChangeTime < 2000) return let val = R.getGMspeed() if (e.key === 'z') { val = 1 } if (e.key === 'x') { val = Math.max(val - 0.25, 0.25) } if (e.key === 'c') { val = Math.min(val + 0.25, 3) } R.setPlayerSpeed(val) R.showSpMsg(val) } if (/up|down/i.test(e.key)) { let vl = R.getGMvolume() let vol = e.key.includes('Up') ? Math.min(vl + 0.03, 1) : Math.max(vl - 0.03, 0) R.setVolume(R.floor(vol)) R.showSpMsg(Math.trunc(vol * 100), '音量') } }) // 滚轮调节音量 window.addEventListener('wheel', async (e) => { const wp = await R.getVideoWrap() const isContains = wp.contains(e.target) if (!isContains) return let vol = R.getGMvolume() if (e.deltaY > 0) { // 减少音量 vol = Math.max(vol - (e.altKey ? 0.1 : 0.03), 0) } else { // 增加音量 vol = Math.min(vol + (e.altKey ? 0.1 : 0.03), 1) } vol = R.floor(vol) R.setVolume(vol) let pVol = Math.trunc(vol * 100) R.showSpMsg(pVol, '音量') }) const initFunc = async () => { ['focus', 'blur'].forEach(v => { window.addEventListener(v, e => { G.focusChangeTime = Date.now() }) }) if (location.host.includes('search.bilibili.com')) { R.judgeIsAppendSoMod() R.watchUrlFunc() } else { let video = await R.getVideo() R.zTimer() video.addEventListener('play', () => { R.initVideoCfg() R.regWpMouseEvt() }) R.regWpMouseEvt() } } initFunc()
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址