Greasy Fork

Greasy Fork is available in English.

哔哩哔哩(B站bilibili)-播放速度及部分操作优化

B站播放器速度自定义(0.25 ~ 3), 支持快捷键(z:正常, x:减少速度, c:增加速度), 支持多标签窗口速度同步, 鼠标中键切换全屏

当前为 2019-06-25 提交的版本,查看 最新版本

// ==UserScript==
// @name         哔哩哔哩(B站bilibili)-播放速度及部分操作优化
// @description  B站播放器速度自定义(0.25 ~ 3), 支持快捷键(z:正常, x:减少速度, c:增加速度), 支持多标签窗口速度同步, 鼠标中键切换全屏
// @namespace    bili
// @version      1.0.1
// @author       vizo
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js
// @include      *://www.bilibili.com/video*
// @include      *://www.bilibili.com/bangumi*
// @run-at       document-end
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// @noframes
// ==/UserScript==
'use strict'

GM_addStyle(`
  #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: 0;
    right: 0;
    bottom: 0;
    left: 0;
    margin: auto;
    z-index: 985;
    display: none;
  }
`)

$(function() {
  let TIMER = null
  
  const timeout = (ms) => {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve()
      }, ms)
    })
  }
  
  const appendMsgLay = async () => {
    let v_warp = $('.bilibili-player-video-wrap')
    let s_msg = v_warp.find('#spsy_msg')
    let speedMsg = `<div id="spsy_msg"></div>`
    if (v_warp.length) {
      if(!s_msg.length) {
        v_warp.append(speedMsg)
      }
    } else {
      await timeout(200)
      appendMsgLay()
    }
  }
  
  const setPlayerSpeed = ( speed = getGmSpeed() ) => {
    appendMsgLay()
    
    let video = $('.bilibili-player-video video')
    video[0].playbackRate = speed
    let store = JSON.parse( getSessionStore() )
    store.video_status.videospeed = speed
    sessionStorage.setItem('bilibili_player_settings', JSON.stringify(store))
  }
  
  const setVideoFullscreen = async () => {
    let video = $('.bilibili-player-video video')
    if (video.length) {
      $('.bilibili-player-video-btn-fullscreen')[0].click()
    } else {
      await timeout(100)
      setVideoFullscreen()
    }
  }
  
  const getGmSpeed = () => {
    return +GM_getValue('bl_player_speed') || 1
  }
  
  const getSessionStore = () => {
    return sessionStorage.getItem('bilibili_player_settings')
  }
  
  const setGmSpeed = (val) => {
    GM_setValue('bl_player_speed', val)
  }
  
  const showSpMsg = (msg) => {
    let mp = $('#spsy_msg')
    clearTimeout(TIMER)
    mp.fadeIn(180)
    mp.text(`速度 ${msg}`)
    
    TIMER = setTimeout(() => {
      mp.fadeOut(250)
    }, 800)
  }
  
  // 右键菜单设置播放速度
  $('body').on('click', '.bilibili-player-contextmenu-subwrapp span', function() {
    let tis = $(this)
    let rate = tis.attr('data-rate')
    setGmSpeed(rate)
    return false
  })
  
  // 切换全屏
  $('body').on('mousedown', '.bilibili-player-video-wrap', function(e) {
    if (e.button === 1) {
      e.preventDefault()
      setVideoFullscreen()
    }
  })
  
  // 键盘快捷键设置播放速度
  $('body').on('keyup', function(e) {
    if (/^[zxc]$/.test(e.key) && !e.ctrlKey && !e.altKey) {
      if (e.target.nodeName !== 'BODY') return
      
      let val = 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)
      }
      setGmSpeed(val)
      showSpMsg(val)
    }
    return false
  })
  
  setInterval(setPlayerSpeed, 500)
})