Greasy Fork is available in English.

视频倍速快捷键

speed up/down video

2020-12-28 يوللانغان نەشرى. ئەڭ يېڭى نەشرىنى كۆرۈش.

// ==UserScript==
// @name         视频倍速快捷键
// @version      0.6
// @description  speed up/down video
// @author       BlueSky
// @match        *://*.bilibili.com/*
// @match        *://*.netflix.com/*
// @match        *://*.youtube.com/*
// @grant        none
// @namespace https://greasyfork.org/users/447360
// ==/UserScript==

(function () {
  'use strict';
  let rate = 1
  let selectors = []
  if (/bilibili/.test(location.hostname)) {
    selectors = [
      'div.bilibili-player-video-top-title',
      'span.tit'
    ]
  } else if (/netflix/.test(location.hostname)) {
    selectors = ['.ellipsize-text h4']
  } else if (/youtube/.test(location.hostname)) {
    selectors = [
      '.ytp-title-link.yt-uix-sessionlink.ytp-title-fullerscreen-link',
      'h1 > yt-formatted-string.style-scope.ytd-video-primary-info-renderer'
    ]
  }

  window.addEventListener('keydown', (e) => {
    if (e.key === '`') {
      rate = 0.5
    } else {
      if ((/youtube/.test(location.hostname))) {
        if (e.key === ']' && rate < 16) {
          rate += 0.5
        } else if (e.key === '[' && rate > 0.25) {
          rate -= 0.5
        } else {
          return
        }
      } else {
        if (e.key === ']' && rate < 16) {
          rate += 0.25
        } else if (e.key === '[' && rate > 0.25) {
          rate -= 0.25
        } else if (e.key === '=' && rate < 16) {
          rate += 0.5
        } else if (e.key === '-' && rate > 0.5) {
          rate -= 0.5
        } else if (e.key === '1') {
          rate = 1
        } else if (e.key === '2') {
          rate = 2
        } else if (e.key === '3') {
          rate = 3
        } else if (e.key === '4') {
          rate = 4
        } else {
          return
        }
      }
    }
    setVideoRate()
    setVideoTitle()
  })

  function getTitle() {
    return selectors
             .map(selector => document.querySelector(selector))
             .filter(el => el && el.innerText)
             .map(el => el.innerText)[0]
  }

  function setVideoRate() {
    console.debug(`rate: ${rate}x`)
    document.querySelector('video').playbackRate = rate
  }

  function setVideoTitle() {
    const title = (getTitle() || '').replace(/^\[.*\] /, '')
    for (const selector of selectors) {
      const el = document.querySelector(selector)
      if (el) {
        el.innerHTML = `[${rate}x] ${title}`
      }
    }
  }
})();