快捷键控制视频倍速、超级快进

快捷键倍速播放(支持B站、腾爱优、百度网盘、油管)。其中B站还可连按箭头超级快进。加速:C +0.25,S +0.5;减速:X -0.25,A -0.5。快进:3次右箭头+30s;4次右箭头+60s。

目前为 2025-03-23 提交的版本。查看 最新版本

// ==UserScript==
// @name          快捷键控制视频倍速、超级快进
// @version       1.0.4
// @description   快捷键倍速播放(支持B站、腾爱优、百度网盘、油管)。其中B站还可连按箭头超级快进。加速:C +0.25,S +0.5;减速:X -0.25,A -0.5。快进:3次右箭头+30s;4次右箭头+60s。
// @author        ww
// @copyright     ww
// @license       MIT
// @match         *://www.bilibili.com/video/av*
// @match         *://www.bilibili.com/video/BV*
// @match         *://www.bilibili.com/cheese/*
// @match         https://v.qq.com/x/*
// @match         https://www.iqiyi.com/*
// @match         https://v.youku.com/*
// @match         https://pan.baidu.com/pfile/video?path=*
// @match         https://www.youtube.com/*
// @grant         GM_addStyle
// @namespace https://gf.qytechs.cn/users/1034870
// ==/UserScript==
/* globals $ waitForKeyElements */
// @[ You can find all source codes in GitHub repo ]
!function() {
    "use strict";

    const duration = 1500;
    const CUSTOM_NORMAL_RATE = 1.25;
    const ORIGINAL_NORMAL_RATE = 1;

    const url = window.location.href;
        console.log("url: "+url);

    let site = 0;
    if(url.indexOf("bilibili") > -1){
        site = 0;
    }else if(url.indexOf("qq.com") > -1){
        site = 1;
    }else if(url.indexOf("iqiyi.com") > -1){
        site = 2;
    }else if(url.indexOf("baidu.com") > -1){
        site = 3;
    }else if(url.indexOf("youtube.com") > -1){
        site = 4;
    }
    console.log("site: "+site);

    const intervalTime = 100; // 每次检查的间隔时间(毫秒)
    const maxChecks = 5000/intervalTime; // 最大检查次数

    let objCss = "";
    let checkCount = 0;
    let specificSite = [3, 4];

    const intervalId = setInterval(() => {
        const element = document.querySelector('video');
        checkCount++;

        if (!isEmpty(element)) {
            if(!specificSite.includes(site)){
                setRate();
                console.log("元素已找到:", element);
                console.log(checkCount);
                clearInterval(intervalId); // 停止循环
            }
        } else if (checkCount >= maxChecks) {
            console.log("已达到最大检查次数,未找到元素");
            clearInterval(intervalId); // 停止循环
        }
    }, intervalTime);

    // 百度网盘特殊处理:① 首次延迟 ② 每隔1秒重设速度,避免暂停键的异常影响
    if(specificSite.includes(site)){
        setTimeout(setRate, 2000);
        setInterval(function() {
            setRecentRate(undefined);
        }, 1000);
    }

    let lock = false;
    let playbackRate = 1.0;


    function setRecentRate(video){
        let recentRate = sessionStorage.getItem("recentRate");
        if(!isEmpty(recentRate)){
            playbackRate = parseFloat(recentRate);
        }
//         百网盘切集后刚取到可能空,再取一次
        if(isEmpty(video)){
            video = document.querySelector('video');
            if(isEmpty(video)){
                console.log("video is empty");
                return;
            }

        }
        setTimeout(function(){
            video.playbackRate = playbackRate;
            showRateBar(playbackRate);
        }, 1000);
       // video.playbackRate = playbackRate;
        console.log("playbackRate after: "+playbackRate);
    }

    // 百度网盘倍速条文字提示
    function showRateBar(playbackRate){
        const pattern = /倍速|X/i;
        let rateCss="vp-video__control-bar--button is-text";
        let rateItems=document.getElementsByClassName(rateCss);
        if(rateItems.length>0){
            for (let i = 0; i < rateItems.length; i++) {
                console.log(rateItems[i].textContent);
                if(pattern.test(rateItems[i].textContent)){
                    rateItems[i].textContent=playbackRate+"X";
                    break;
                }
            }
        }
    }

    // 覆盖默认的url改变触发的方法
    (function(history) {
        var pushState = history.pushState;
        var replaceState = history.replaceState;
        let video = document.querySelector('video');

        history.pushState = function(state) {
            pushState.apply(history, arguments);
            console.log('pushState URL changed to:', window.location.href);
            setRecentRate(video);
        };

        history.replaceState = function(state) {
            replaceState.apply(history, arguments);
            console.log('replaceState URL changed to:', window.location.href);
            setRecentRate(video);
        };
    })(window.history);

    function setRate(){

        //B站右侧如果有分集列表,则给予更多展示高度
        let playlist = document.querySelector("#mirror-vdcon > div.right-container > div > div.rcmd-tab > div.video-pod.video-pod > div.video-pod__body");
        if(!isEmpty(playlist)){
            playlist.style.maxHeight = "650px";
        }

        let video = document.querySelector('video');
        // 初始化倍速
        setRecentRate(video);

        // 监听键盘事件
        document.addEventListener('keydown', (event) => {
            let displayRateFlag = false;
            let setSessionRateFlag = true;

            switch (event.key.toLowerCase()) {
                case 'z':
                    console.log(video.playbackRate);
                    // 如果本是正常速度,则切到原倍速;否则恢复正常
                    if(video.playbackRate === CUSTOM_NORMAL_RATE){
                        let recentRate = sessionStorage.getItem("recentRate");
                        if(!isEmpty(recentRate)){
                            playbackRate = parseFloat(recentRate);
                            displayRateFlag = true;
                        }
                    }else{
                        playbackRate = CUSTOM_NORMAL_RATE; // 恢复正常速度
                    }
                    setSessionRateFlag = false;
                    break;
                case 's':
                    playbackRate += 0.5;
                    displayRateFlag = true;
                    break;
                case 'a':
                    playbackRate -= 0.5;
                    displayRateFlag = true;
                    if (playbackRate < 0.25) {
                        playbackRate = 0.5; // 设置最低倍速
                    }
                    break;
                case 'c':
                    displayRateFlag = true;
                    playbackRate += 0.25;
                    break;
                case 'x':
                    playbackRate -= 0.25;
                    displayRateFlag = true;
                    if (playbackRate < 0.25) {
                        playbackRate = 0.25; // 最低倍速为0.25
                    }
                    break;
                case 'f':
                    if(site !== 0 && site !== 4){ // B站、油管本身支持F全屏键,若不排除会有小问题
                        if(isFullscreen()){
                            document.exitFullscreen();
                        }else{
                            video.requestFullscreen();
                        }
                    }
                    break;
            }
            console.log("now rate is "+playbackRate);
            video.playbackRate = playbackRate;
            showRateBar(playbackRate);
            if(setSessionRateFlag){
                sessionStorage.setItem("recentRate", playbackRate);
            }

            if(displayRateFlag){
                // 0 b站 1腾讯视频
                if(site === 0){
                    const element = document.querySelector("#bilibili-player > div > div");
                    if(isEmpty(element)){
                        return;
                    }
                    element.setAttribute("data-ctrl-hidden", "false");

                    // 按倍速键的计数器,按倍速键加1,duation时间后减1,并判断减完是否≤1,效果是最后一次按倍速键后才隐藏底部条。
                    let showCount = sessionStorage.getItem("show");
                    if(isEmpty(showCount)){
                        sessionStorage.setItem("show", 1);
                    }else{
                        sessionStorage.setItem("show", parseInt(showCount) + 1);
                    }

                    setTimeout(() => {
                        let showCount2 = sessionStorage.getItem("show");
                        if(showCount2 <= 1){
                            element.setAttribute("data-ctrl-hidden", "true");
                            sessionStorage.setItem("show", "");
                        }else{
                            sessionStorage.setItem("show", parseInt(showCount2) - 1);
                        }
                    }, duration);
                }
                if(site === 1){
                    const element = document.querySelector("#player > div.plugin_ctrl_txp_bottom");
                    element.classList.remove("txp_none");

                    setTimeout(() => {
                        element.classList.add("txp_none");
                    }, duration);
                }

            }

        });
    }

    function isEmpty(item){
        if(item===null || item===undefined || item.length===0){
            return true;
        }else{
            return false;
        }
    }

    function isFullscreen() {
        return (
            document.fullscreenElement ||
            document.msFullscreenElement ||
            document.mozFullScreenElement ||
            document.webkitFullscreenElement ||
            false
        );
    }

    // 快进、快退
    // 初始化变量
    let lastKeyPressTime = 0;
    let keyPressCount = 0;
    const doublePressThreshold = 350; // 两次按键的时间间隔阈值,单位毫秒

    // 监听键盘按键事件
    document.addEventListener('keydown', function (event) {
        const currentTime = new Date().getTime();

        // 检查按下的键是否是右箭头键或左箭头键
        if (event.key === 'ArrowRight' || event.key === 'ArrowLeft') {
            // 检查两次按键的时间间隔是否小于阈值
            if (currentTime - lastKeyPressTime < doublePressThreshold) {
                keyPressCount++; // 增加按键计数
            } else {
                keyPressCount = 1; // 重置按键计数
            }

            // 更新最后一次按键时间
            lastKeyPressTime = currentTime;

            // 获取视频元素
            const video = document.querySelector('video');
            if (video) {
                if (event.key === 'ArrowRight') {
                    // 右箭头键逻辑
                    if (keyPressCount === 3) {
                        video.currentTime += 15; // 快进30秒
                    } else if (keyPressCount === 4) {
                        video.currentTime += 25; // 快进1分钟,即:25(快进25秒)+30(触发按3次的30秒)+5(触发默认的5秒)
                        keyPressCount = 0; // 重置计数
                    }
                } else if (event.key === 'ArrowLeft') {
                    // 左箭头键逻辑
                    if (keyPressCount === 3) {
                        video.currentTime -= 15; // 快退30秒
                    } else if (keyPressCount === 4) {
                        video.currentTime -= 25; // 快退60秒
                        keyPressCount = 0; // 重置计数
                    }
                }
            }
        } else {
            // 如果按下其他键,重置计数
            keyPressCount = 0;
        }
    });

    function addCustomStyles() {
        var css = `
        .tool-box {
            display: none;
            position: absolute;
            bottom: 11rem;
            left: 50%;
            transform: translate(-50%, 0%);
            width: 5rem;
            background: rgba(0, 0, 0, 0.7);
            color: white;
            padding: 0.5rem;
            border-radius: 5px;
            font-size: 1rem;
            text-align: center;
            z-index: 99999   !important;
        }
    `;
        GM_addStyle(css);
    }
    addCustomStyles();

    var box=getBox();
    console.log(box);
    document.body.appendChild(box);

    function getBox(){
        var box = document.createElement("div");
        box.classList.add("tool-box");
        return box;
    }

}();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址