Greasy Fork

Greasy Fork is available in English.

自定义哔哩哔哩视频播放速度,记住播放速度、位置

可以使用按键 z(恢复1倍速)、x(减0.1倍速)、c(加0.1倍速),s(记录播放速度,下次打开视频直接使用记录的播放速度),d(删除记录的播放速度),

当前为 2021-05-07 提交的版本,查看 最新版本

// ==UserScript==
// @name         自定义哔哩哔哩视频播放速度,记住播放速度、位置
// @namespace    http://tampermonkey.net/
// @version      0.1.5
// @description  可以使用按键 z(恢复1倍速)、x(减0.1倍速)、c(加0.1倍速),s(记录播放速度,下次打开视频直接使用记录的播放速度),d(删除记录的播放速度),
// @author       felix
// @icon         chrome://favicon/http://www.bilibili.com/
// @match        https://www.bilibili.com/video/*
// @grant        GM_registerMenuCommand
// @grant        GM_unregisterMenuCommand
// ==/UserScript==
(function () {
    'use strict';

    // ===================================================配置区=====================================================================================
    var STORAGE_KEY = {
        BILIBILI_VIDEO_SPEED: "bilibili_video_speed",
        BILIBILI_VIDEO_CURRENT_TIME: "bilibili_video_current_time"
    };

    var SETTING = {
        STEP_SIZE: 0.1,
        MAX_SPEED: 5,
        MIN_SPEED: 0.1,
        REMEMBER_SPEED_MENU_ID: null,
        REMEMBER_CURRENT_TIME_MENU_ID: null,
        SAVE_CURRENT_TIME_LISTENER: null
    };

    // ===================================================加载区=====================================================================================
    var autoAddInterval = setInterval(loading, 5000);

    function loading() {
        clearInterval(autoAddInterval);
        addButton();
        loadSpeed();
        loadCurrentTime();
    }

    // 添加按钮
    function addButton() {
        var div = document.createElement("div");
        div.innerHTML = '<button id="reduce" style="width:15px;margin:0 3px">-</button><button style="width:30px"><sapn id="speed">1<span/></button><button id="add" style="width:15px;margin:0 3px">+</button>';
        document.getElementById("arc_toolbar_report").appendChild(div);
        document.getElementById("reduce").onclick = function () { reduceSpeed(); };
        document.getElementById("add").onclick = function () { addSpeed(); };
    }

    // 加载播放速度
    function loadSpeed() {
        var speed = localStorage.getItem(STORAGE_KEY.BILIBILI_VIDEO_SPEED);
        if (speed) {
            changeSpeed(speed);
            loadRemoveSpeedMenu();
        } else {
            loadSaveSpeedMenu();
        }
    }

    // 加载播放时间
    function loadCurrentTime() {
        var currentTime = localStorage.getItem(getCurrentTimeUrlKey());
        if (currentTime) {
            changeCurrentTime(currentTime);
            openSaveCurrentTimeListener();
        } else {
            closeSaveCurrentTimeListener();
        }
    }

    // ==================================================菜单区=================================================================================
    function loadSaveSpeedMenu() {
        SETTING.REMEMBER_SPEED_MENU_ID = GM_registerMenuCommand("记住播放速度", setSpeedToStorage);
    }

    function loadRemoveSpeedMenu() {
        SETTING.REMEMBER_SPEED_MENU_ID = GM_registerMenuCommand("忘记播放速度", removeSpeedFromStorage);
    }

    function loadSaveCurrentTimeMenu() {
        SETTING.REMEMBER_CURRENT_TIME_MENU_ID = GM_registerMenuCommand("开启记住播放时间", openSaveCurrentTimeListener);
    }

    function loadRemoveCurrentTimeMenu() {
        SETTING.REMEMBER_CURRENT_TIME_MENU_ID = GM_registerMenuCommand("关闭记住播放时间", closeSaveCurrentTimeListener);
    }

    // 保存播放速度到localStorage
    function setSpeedToStorage() {
        localStorage.setItem(STORAGE_KEY.BILIBILI_VIDEO_SPEED, getVideoSpeed());
        if (SETTING.REMEMBER_SPEED_MENU_ID) GM_unregisterMenuCommand(SETTING.REMEMBER_SPEED_MENU_ID);
        loadRemoveSpeedMenu();
    }

    // 从localStorage中删除保存的播放速度
    function removeSpeedFromStorage() {
        localStorage.removeItem(STORAGE_KEY.BILIBILI_VIDEO_SPEED);
        if (SETTING.REMEMBER_SPEED_MENU_ID) GM_unregisterMenuCommand(SETTING.REMEMBER_SPEED_MENU_ID);
        loadSaveSpeedMenu();
    }

    // 开启监听器保存当前视频观看时间
    function openSaveCurrentTimeListener() {
        SETTING.SAVE_CURRENT_TIME_LISTENER = setInterval(function () {
            localStorage.setItem(getCurrentTimeUrlKey(), getVideoCurrentTime());
        }, 10000);
        if (SETTING.REMEMBER_CURRENT_TIME_MENU_ID) GM_unregisterMenuCommand(SETTING.REMEMBER_CURRENT_TIME_MENU_ID);
        loadRemoveCurrentTimeMenu();
    }

    // 关闭保存当前视频观看时间监听器
    function closeSaveCurrentTimeListener() {
        if (SETTING.SAVE_CURRENT_TIME_LISTENER) window.clearInterval(SETTING.SAVE_CURRENT_TIME_LISTENER);
        localStorage.removeItem(getCurrentTimeUrlKey());
        if (SETTING.REMEMBER_CURRENT_TIME_MENU_ID) GM_unregisterMenuCommand(SETTING.REMEMBER_CURRENT_TIME_MENU_ID);
        loadSaveCurrentTimeMenu();
    }
    // ===================================================键盘监听区=====================================================================================
    document.onkeydown = function (e) {
        if (e.target.nodeName !== 'BODY') return;
        if (/^[zxcZXC]$/.test(e.key)) {
            if (e.key === 'z' || e.key === 'Z') changeSpeed(1);
            if (e.key === 'x' || e.key === 'X') reduceSpeed();
            if (e.key === 'c' || e.key === 'C') addSpeed();
        }
        if (/^[sdSD]$/.test(e.key)) {
            if (e.key === 's' || e.key === 'S') setSpeedToStorage();
            if (e.key === 'd' || e.key === 'D') removeSpeedFromStorage();
        }
    };

    // ===================================================获取控件区=====================================================================================
    // 获取 video控件
    function getVideo() {
        return document.querySelector('video');
    }

    // 获取当前视频的url key
    function getCurrentTimeUrlKey() {
        return STORAGE_KEY.BILIBILI_VIDEO_CURRENT_TIME + "_" + window.location.href;
    }

    // 获取当前时间
    function getVideoCurrentTime() {
        return getVideo().currentTime;
    }

    // 获取当前播放速度
    function getVideoSpeed() {
        return getVideo().playbackRate;
    }

    // ===================================================方法区=====================================================================================
    // 减速
    function reduceSpeed(stepSize) {
        if (!stepSize) stepSize = SETTING.STEP_SIZE;
        var playSpeed = Number((Number(document.getElementById("speed").innerText) * 10 - stepSize * 10) / 10).toFixed(1);
        changeSpeed(playSpeed);
    }

    // 加速
    function addSpeed(stepSize) {
        if (!stepSize) stepSize = SETTING.STEP_SIZE;
        var playSpeed = Number((Number(document.getElementById("speed").innerText) * 10 + stepSize * 10) / 10).toFixed(1);
        changeSpeed(playSpeed);
    }

    // 改变播放速度
    function changeSpeed(playSpeed) {
        if (playSpeed && playSpeed >= SETTING.MIN_SPEED && playSpeed <= SETTING.MAX_SPEED) {
            getVideo().playbackRate = playSpeed;
            document.getElementById("speed").innerText = playSpeed;
        }
    }

    // 改变当前播放时间
    function changeCurrentTime(currentTime) {
        getVideo().currentTime = currentTime;
    }
})();