简单脚本实现B站视频快捷键播放

[广告:最高 ¥2000 红包]阿里云服务器、主机等产品通用,可叠加官网常规优惠使用 | 限时领取

刷V2ex看到一个帖子:为什么国内视频网站快捷键极少或者没有? – V2EX

深有同感!!!

我经常看bilibili.com。大部分视频讲得很慢,经常需要倍数播放,有快捷键的话,会方便很多。

上网找了下,已经有很多这样的快捷键脚本,如:

这些脚本都很好,但我并不是很想用,因为这类脚本有三个问题:

  1. 为了适配多个网站,导致代码量巨大,会把网页拖慢。
  2. 快捷键众多(不是自己设置的)记不住。
  3. 按键冲突,不是自己设置的键,容易与其它设置相冲突

所以,我自己写一个适用于B站的油猴脚本。

原理非常简单,即监听文档的按键弹起事件。如果相应的按键有对应的方法,就执行方法,一般为触发视频播放控件的click事件。

使用最新ES2021可选链操作符 – JavaScript | MDN,不需要再显示判断对应的方法是否存在,使得代码更为简洁。

主要实现的功能(只在chrome中测试):

  • 「B」:弹幕开关
  • 「M」:静音/取消静音
  • 「/」:定位搜索栏
  • 「C」:字幕开关
  • 「K」:暂停播放 / 恢复播放(默认为空格键,但视频播放器没有获得焦点时,空格键默认行为是向下翻页,所以新增加了K键)
  • 「<」与「>」:改变视频播放速度,如: 0.5、0.25、正常、1.25、1.5、2
  • 「+」与「-」:同上
  • 「G」:视频点赞(未能实现一键三连的功能,哪位帅气的小伙帮我来实现?)
完整代码如下:
// ==UserScript==
// @name         B站视频播放快捷键
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  B站视频快捷键播放
// @author       码中人 http://www.mzh.ren
// @match        *://*.bilibili.com/*
// @grant        none
// ==/UserScript==
(function () {
    // 「/」:把浮標放到 Youtube 搜尋列
    // 「F」:全畫面
    // 「Esc」:離開全畫面 / 離開 Youtube 搜尋列
    // 「M」:靜音 / 關閉靜音
    // 「C」:開啟字幕 / 關閉字幕
    // 「B」:切換字幕背景顏色
    // 「K」:暫停播放 / 恢復播放
    // 「空白鍵」:暫停播放 / 恢復播放
    // 「J」:快退 10 秒
    // 「L」:快進 10 秒
    // 「左箭咀」:影片播放時,快退 5 秒
    // 「右箭咀」:影片播放時,快進 5 秒
    // 「上箭咀」:調高 5% 音量
    // 「下箭咀」:調低 5% 音量
    // 「1-9」:影片播放時,跳至影片的 10% 至 90% 位置;例如影片長度 100 分鐘,按「1」,即可跳至影片的第 10 分鐘畫面(10%)。
    // 「0」:從頭播放
    // 「Home」:從頭播放
    // 「End」:跳至片尾 / 下一段影片(Playlist)
    // 「Shift」+「N」:下一段影片(Playlist)
    // 「Shift」+「P」:上一段影片(Playlist)
    // 「,」:慢退(影片在暫停播放狀態)
    // 「.」:慢進(影片在暫停播放狀態)
    // 「<」與「>」:改變影片播放速度,倍速間距為 0.5、0.25、正常、1.25、1.5、2

    let $ = document.querySelector.bind(document);

    function showControlBar() {
        $('.bilibili-player-area').classList.add('video-control-show')
    }

    function startOrPause() {
        $('.bilibili-player-video-btn').click();
    }

    function buiSwitch() {
        const buiBtn = $('input[type="checkbox"].bui-switch-input');
        buiBtn.checked = !buiBtn.checked;
    }

    function subtitle() {
        const subtitleBtn = $('.bilibili-player-iconfont-subtitle');
        subtitleBtn.click();
    }

    function fullScreen() {
        const fsBtn = $('.bilibili-player-video-web-fullscreen button');
        fsBtn.click();
    }

    function volumnSwitch() {
        const volumnBtn = $('.bilibili-player-video-btn-volume button');
        volumnBtn.click();
    }

    function searchFocus(){
        const searchInput = $('.nav-search-keyword');
        searchInput.focus()
    }

    function playSpeed(forward) {
        const currentSpeedItem = $('.bilibili-player-active');
        if (forward) {
            currentSpeedItem.previousSibling?.click?.();
        } else {
            currentSpeedItem.nextSibling?.click?.();
        }
    }

    function fast() {
        playSpeed(true)
    }

    function slow() {
        playSpeed(false)
    }

    function like(){
        const likeBtn = $('.ops .like');
        likeBtn.click();
    }

    const KEYS_HANDLERS = {
        'KeyB': buiSwitch,
        'KeyM': volumnSwitch,
        'KeyK': startOrPause,
        'Comma': slow,
        'Period': fast,
        'Equal': fast,
        'Minus': slow,
        'Slash':searchFocus,
        'KeyC': subtitle,
        'KeyG':like
    }

    document.addEventListener('keyup', (e) => {
        console.log(e.code)
        KEYS_HANDLERS[e.code]?.();
        showControlBar();
    })

})()
码中人 微信公众号

关注微信公众号

码中人 微信公众号