Greasy Fork

Greasy Fork is available in English.

B站倍播快捷键_好用!

按下z减速,按下x加速,按下c回1倍速。加减速倍率为0.2,会记住之前的播放速度

目前为 2022-02-09 提交的版本。查看 最新版本

// ==UserScript==
// @name         B站倍播快捷键_好用!
// @version      1.0
// @description  按下z减速,按下x加速,按下c回1倍速。加减速倍率为0.2,会记住之前的播放速度
// @author       Alan996
// @icon         https://i1.hdslb.com/bfs/face/a809a3b8407840ae00032360108261fcf503d38a.jpg@96w_96h_1c_1s.webp
// @include      https://www.bilibili.com/*
// @match        https://www.bilibili.com/video/*
// @namespace    hahahahahahahahalahahahahahaha
// @grant        none
// @license      GPL
//thanks for @tomoya92 @csXLJ
// ==/UserScript==

(function () {
    "use strict";

    const THIRD_VIDEO_PLUGIN_DANMU_STATUS = "third_video_plugin_danmu_status";
    const THIRD_VIDEO_PLUGIN_SPEED = "a_third_video_plugin_speed";
    const THIRD_VIDEO_PLUGIN_SPEEDS = "a_third_video_plugin_speeds";

    let videoSpeedElement = document.createElement("div"),
        currentHref = "",
        viewReportDiv;
    videoSpeedElement.setAttribute("id", "video_speed_div");

    let style = document.createElement("style");
    style.type = "text/css";
    style.innerHTML = "#video_speed_div button, #third_video_plugin_btn { outline: 0; padding: 3px 5px; margin-left: 10px; background-color: #e2e0e0; border: 0; color: #222; cursor: pointer;} .video_speed_div-button-active { border: 0!important; background-color: #ffafc9!important; color: #fff!important; }";
    document.getElementsByTagName("head").item(0).appendChild(style);

    let _interval = setInterval(function () {
        if (document.querySelector(".bb-comment") && document.getElementById("video_speed_div") === null) {
            addSpeedBtns();
        }
    }, 100);

    function keyd(e) {
        let speed;
        let a_third_video_plugin_speed = localStorage.getItem(THIRD_VIDEO_PLUGIN_SPEED);
        if (!a_third_video_plugin_speed) {
            a_third_video_plugin_speed = "1";
            localStorage.setItem(THIRD_VIDEO_PLUGIN_SPEED, a_third_video_plugin_speed);
            speed = parseFloat(a_third_video_plugin_speed);
        } else {
            speed = parseFloat(a_third_video_plugin_speed);
        }
        var video = document.querySelector('.bilibili-player-video-inner');
        if (e.key == "x") {
            if (speed == 16) {
                speed = 16;
            } else {
                speed = speed + 0.25;
                localStorage.setItem(THIRD_VIDEO_PLUGIN_SPEED, speed.toString());
            }
        } else if (e.key == "z") {
            if (speed == 0) {
                speed = 0;
            } else {
                speed = speed - 0.25;
                localStorage.setItem(THIRD_VIDEO_PLUGIN_SPEED, speed.toString());
            }
        } else if (e.key == "c") {
            speed = 1;
            localStorage.setItem(THIRD_VIDEO_PLUGIN_SPEED, speed.toString());
        }
    }

    document.body.removeEventListener('keydown', keyd);
    document.body.addEventListener('keydown', keyd);

    function addSpeedBtns() {
        viewReportDiv = document.querySelector("#viewbox_report").querySelector(".video-data:last-child");
        // 创建一个设置倍速的按钮
        let speedsettingsbtn = document.createElement("button");
        speedsettingsbtn.innerHTML = "  S  ";
        speedsettingsbtn.style.backgroundColor = "black";
        speedsettingsbtn.style.color = "white";
        speedsettingsbtn.setAttribute("id", "third_video_plugin_btn");
        speedsettingsbtn.addEventListener("click", speedsettingsevent);
        viewReportDiv.appendChild(speedsettingsbtn);

        initBtn();

        videoSpeedElement.style.width = "100%";
        videoSpeedElement.style.height = "24px";

        viewReportDiv.appendChild(videoSpeedElement);

        clearInterval(_interval);

        // 加载之间已经设置的速度, 在同一个页面中切换视频后,设置的速度就没了,这里用一个定时器,200ms设置一下
        setInterval(function () {
            let a_third_video_plugin_speed = localStorage.getItem(THIRD_VIDEO_PLUGIN_SPEED);
            if (!a_third_video_plugin_speed) {
                a_third_video_plugin_speed = "1";
                localStorage.setItem(THIRD_VIDEO_PLUGIN_SPEED, a_third_video_plugin_speed);
            }
            // 设置倍速按钮高亮
            hightlightBtn(a_third_video_plugin_speed);

            let videoObj = document.querySelector("video");
            if (!videoObj) videoObj = document.querySelector("bwp-video");
            if (videoObj) {
                videoObj.playbackRate = parseFloat(a_third_video_plugin_speed);

                let nextBtn = document.querySelector(".bilibili-player-iconfont-next");
                if (nextBtn) {
                    let currentTime = videoObj.currentTime;
                    let totalTime = videoObj.duration;
                    if (totalTime - currentTime < 0.5) {
                        // 视频还剩500ms的时候自动跳转到下一个视频,防止出现充电界面
                        document.querySelector(".bilibili-player-iconfont-next").click();
                    }
                }

                let broswerPath = window.location.href;
                if (currentHref !== broswerPath) {
                    currentHref = broswerPath;
                    pageContentChange();
                }

                let switchBtn = document.querySelector(".bilibili-player-video-danmaku-switch");
                if (switchBtn) switchBtn.addEventListener("click", danmuClickHandler, false);
            }
        }, 200);
    }

    function danmuClickHandler(e) {
        if (e.isTrusted) {
            let span = document.querySelector(".bilibili-player-video-danmaku-switch>.choose_danmaku");
            if (span.textContent === "开启弹幕") {
                writeDanmuStatus(1);
            } else {
                writeDanmuStatus(2);
            }
        }
    }

    function initBtn() {
        let speedArr = getStorageSpeeds();
        if (speedArr.length === 0) {
            speedArr = [0.5, 1, 1.5, 2, 2.5, 3, 4, 5, 16];
            localStorage.setItem(THIRD_VIDEO_PLUGIN_SPEEDS, speedArr.join(","));
        }
        for (let i = 0; i < speedArr.length; i++) {
            let speed = speedArr[i];
            let btn = document.createElement("button");
            btn.innerHTML = "x" + speed;
            btn.style.width = "40px";
            btn.setAttribute("id", "third_video_plugin_btn_" + speed);
            btn.addEventListener("click", changeVideoSpeed);
            videoSpeedElement.appendChild(btn);
        }
    }

    function getStorageSpeeds() {
        let storageSpeeds = localStorage.getItem(THIRD_VIDEO_PLUGIN_SPEEDS);
        if (!storageSpeeds) return [];
        return storageSpeeds.split(",");
    }

    function speedsettingsevent() {
        let a = window.prompt("输入倍速,以英文逗号隔开。", getStorageSpeeds().join(","));
        if (!a) return;
        a = a.replace(/\s+/g, "");
        let speeds = a.split(",");
        for (let i = 0; i < speeds.length; i++) {
            let speed = parseInt(speeds[i]);
            if (isNaN(speed)) return;
        }
        localStorage.setItem(THIRD_VIDEO_PLUGIN_SPEEDS, a);
        // clear btns
        let btns_length = videoSpeedElement.childNodes.length;
        for (let i = 0; i < btns_length; i++) {
            let btn = videoSpeedElement.childNodes[0];
            videoSpeedElement.removeChild(btn);
        }
        let storageSpeed = localStorage.getItem(THIRD_VIDEO_PLUGIN_SPEED);
        if (speeds.indexOf(storageSpeed) === -1) localStorage.setItem(THIRD_VIDEO_PLUGIN_SPEED, "1");
        // add new btns
        initBtn();
    }

    function pageContentChange() {
        setTimeout(function () {
            // 弹幕设置
            let storageDanmuStatus = localStorage.getItem(THIRD_VIDEO_PLUGIN_DANMU_STATUS);
            if (!storageDanmuStatus) {
                storageDanmuStatus = 1; // 默认开启
                writeDanmuStatus(1);
            }
            if (parseInt(storageDanmuStatus) !== 1) {
                document.querySelector(".bui-checkbox").click();
            }
        }, 1000);
    }

    function writeDanmuStatus(status) {
        if (status === 1 || status === 2) {
            localStorage.setItem(THIRD_VIDEO_PLUGIN_DANMU_STATUS, status);
        }
    }

    function changeVideoSpeed(e) {
        let speed = parseFloat(e.target.innerHTML.replace("x", ""));
        localStorage.setItem(THIRD_VIDEO_PLUGIN_SPEED, speed);
        hightlightBtn(speed);
    }

    function hightlightBtn(speed) {
        let currentSpeedBtn = document.getElementById("third_video_plugin_btn_" + speed);
        if (currentSpeedBtn && currentSpeedBtn.className.indexOf("video_speed_div-button-active") === -1) {
            for (let i = 0; i < videoSpeedElement.childNodes.length; i++) {
                let btn = videoSpeedElement.childNodes[i];
                btn.setAttribute("class", "");
            }
            currentSpeedBtn.setAttribute("class", "video_speed_div-button-active");
        }
    }
})();