Greasy Fork

Greasy Fork is available in English.

黄金右键-灵活控制视频倍速(改)-Golden Right-Flexibly control the playback rate of videos (edited)

长按"→"键加速倍速播放, 松开"→"键恢复用户初始速度, 点击">"加速倍速增加, 点击"<"加速倍速减小, 点击"?"重置正常速度到1倍速, 重置加速速度到2倍速, 灵活追剧看视频~ 支持b站、YouTube、腾讯视频、优酷...

// ==UserScript==
// @name         黄金右键-灵活控制视频倍速(改)-Golden Right-Flexibly control the playback rate of videos (edited)
// @description     长按"→"键加速倍速播放, 松开"→"键恢复用户初始速度, 点击">"加速倍速增加, 点击"<"加速倍速减小, 点击"?"重置正常速度到1倍速, 重置加速速度到2倍速, 灵活追剧看视频~ 支持b站、YouTube、腾讯视频、优酷...
// @description:en  Hold '→': speed up playback, release '→': return to normal speed, press '<': decrease faster playback speed, press '>': increase faster playback speed, press '?': reset normal speed to 1 and faster playback speed to 2. 
// @namespace    http://tampermonkey.net/
// @version      1.1.1.7
// @author       SkyJin (作者) & SteveQian (修改)
// @include     http://*
// @include     https://*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    // 按键分配
    // →:39, >:190, <:188, ?:191
    let Forward_KeyCode = 39        // →:39  点按 正常跳播 和 长按 加速前进播放 键
    let Forward_IncRate_KeyCode = 190    // >:190 增加 加速前进播放 速度 键
    let Forward_DecRate_KeyCode = 188    // <:188 减小 加速前进播放 速度 键
    let Forward_ResetRate_KeyCode = 191         // ?:191 重置 正常播放 速度 和 加速前进播放 速度 键

    const Init_Normal_Rate_Forward = 1 // 初始 正常 播放 速度
    const Init_Faster_Rate_Forward = 2 // 初始 加速前进 播放 速度
    let Current_Normal_Rate_Forward = 1 // 当前 正常 播放 速度
    let Current_Faster_Rate_Forward = 2 // 当前 加速前进 播放 速度
    let Count_Forward_Key_Down = 0 // 加速前进 播放 键 点击时间
    const Add_Time_Forward = 7 // 正常跳播 前进时间

    // 增加 加速前进播放 速度 键 和 减小 加速前进播放 速度 键 是否被按下
    let is_Forward_IncRate_Key_Down = false // 增加 加速前进播放 速度 键 是否被按下
    let is_Forward_DecRate_Key_Down = false // 减小 加速前进播放 速度 键 是否被按下

    let is_Forward_Key_Down = false // 是否正在 加速前进播放

    let page_video

    function makeArray(arr) {
        if (arr.item) {
            var len = arr.length;
            var array = [];
            while (len--) {
                array[len] = arr[len];
            }
            return array;
        }
        return Array.prototype.slice.call(arr);
    }

    const init = () => {
        if (location.origin.indexOf("youtube.com") > -1) {
            document.body.addEventListener("keydown", Forward_Key_Down_Event_YT, true);
            document.body.parentElement.addEventListener("keyup", Forward_Key_Up_Event_YT, true);
        } else {
            document.body.addEventListener("keydown", Forward_Key_Down_Event, true);
            document.body.parentElement.addEventListener("keyup", Forward_Key_Up_Event, true);
        }

        document.body.addEventListener("keydown", Forward_IncRate_Key_Down_Event, true)
        document.body.addEventListener("keydown", Forward_DecRate_Key_Down_Event, true)

        document.body.parentElement.addEventListener("keyup", Forward_IncRate_Key_Up_Event, true)
        document.body.parentElement.addEventListener("keyup", Forward_DecRate_Key_Up_Event, true)

        document.body.parentElement.addEventListener("keyup", Forward_ResetRate_Key_Up_Event, true)
        
    };

/*
.............########..#######..########......#######..########.##.....##.########.########...######.
.............##.......##.....##.##.....##....##.....##....##....##.....##.##.......##.....##.##....##
.............##.......##.....##.##.....##....##.....##....##....##.....##.##.......##.....##.##......
.............######...##.....##.########.....##.....##....##....#########.######...########...######.
.............##.......##.....##.##...##......##.....##....##....##.....##.##.......##...##.........##
.............##.......##.....##.##....##.....##.....##....##....##.....##.##.......##....##..##....##
.............##........#######..##.....##.....#######.....##....##.....##.########.##.....##..######.
*/
    const getPageVideo = () => {
        console.log("正在查找可用的Video Element...");
        const allVideoElementArray = makeArray(
            document.getElementsByTagName("video")
        ).concat(makeArray(document.getElementsByTagName("bwp-video")));
        console.log(allVideoElementArray);
        const page_video = Array.prototype.find.call(
            allVideoElementArray,
            (e) => {
                if (checkPageVideo(e)) return e;
            }
        );

        if (page_video) {
            console.log("找到正在播放的Video Element!");
            return page_video;
        } else {
            console.log("找不到正在播放的Video Element");
        }
    };
    const checkPageVideo = (v) => {
        if (v) {
            return v.offsetWidth > 9 && !v.paused;
        } else {
            return false;
        }
    };
    const relativeEvent = {
        _stopper: (e) => e.stopPropagation(),
        // 目前针对腾讯视频
        shouldPrevent:
            location.origin.indexOf("qq.com") > -1 ||
            location.origin.indexOf("wetv.vip") > -1,
        prevent() {
            document.body.addEventListener("ratechange", this._stopper, true);
            document.body.addEventListener("timeupdate", this._stopper, true);
        },
        allow() {
            document.body.removeEventListener(
                "ratechange",
                this._stopper,
                true
            );
            document.body.removeEventListener(
                "timeupdate",
                this._stopper,
                true
            );
        },
    };
    // 加速前进播放 键按下事件,加速播放开始
    const Forward_Key_Down_Event = (e) => {
        if (e.keyCode !== Forward_KeyCode) return
        e.stopPropagation()

        // 加速前进播放键时间计数+1
        Count_Forward_Key_Down++

        // 长按按键-开始
        if (Count_Forward_Key_Down === 2) {
            if (checkPageVideo(page_video) || (page_video = getPageVideo())) {
                is_Forward_Key_Down = true
                relativeEvent.shouldPrevent && relativeEvent.prevent()
                Current_Normal_Rate_Forward = page_video.playbackRate
                page_video.playbackRate = Current_Faster_Rate_Forward
                console.log(Current_Faster_Rate_Forward + '倍前进加速播放中')
            }
        }
    };
    // 加速前进播放 键松开事件,加速播放结束
    const Forward_Key_Up_Event = (e) => {
        if (e.keyCode !== Forward_KeyCode) return
        e.stopPropagation()

        // 单击 加速前进播放 键
        if (Count_Forward_Key_Down === 1) {
            if (checkPageVideo(page_video) || (page_video = getPageVideo())) {
                page_video.currentTime += Add_Time_Forward
                console.log('前进' + Add_Time_Forward + '秒')
            }
        }

        // 长按 加速前进播放 键-结束
        // if (page_video && page_video.playbackRate !== Normal_Rate_Forward) {
        if (page_video && is_Forward_Key_Down) {
            is_Forward_Key_Down = false
            page_video.playbackRate = Current_Normal_Rate_Forward
            relativeEvent.shouldPrevent && relativeEvent.allow()
            console.log('前进加速播放结束')
        }
        // 计数-重置
        Count_Forward_Key_Down = 0
    }

/*
    .########..#######..########.....##....##..#######..##.....##.########.##.....##.########..########
    .##.......##.....##.##.....##.....##..##..##.....##.##.....##....##....##.....##.##.....##.##......
    .##.......##.....##.##.....##......####...##.....##.##.....##....##....##.....##.##.....##.##......
    .######...##.....##.########........##....##.....##.##.....##....##....##.....##.########..######..
    .##.......##.....##.##...##.........##....##.....##.##.....##....##....##.....##.##.....##.##......
    .##.......##.....##.##....##........##....##.....##.##.....##....##....##.....##.##.....##.##......
    .##........#######..##.....##.......##.....#######...#######.....##.....#######..########..########
*/
    const getPageVideo_YT = () => {
        console.log("正在查找可用的Video Element...");
        let pv;

        if (document.getElementById("ytd-player") && checkPageVideo_YT(document.getElementById("ytd-player").player_))
            pv = document.getElementById("ytd-player").player_

        if (pv) {
            console.log("找到正在播放的Video Element!");
            return pv;
        } else {
            console.log("找不到正在播放的Video Element");
        }
    };
    const checkPageVideo_YT = (v) => {
        if (v) {
            return v.getPlayerState() == 1;
        } else {
            return false;
        }
    };
    const Forward_Key_Down_Event_YT = (e) => {
        if (e.keyCode !== Forward_KeyCode) return;
        e.stopPropagation();

        // 计数+1
        Count_Forward_Key_Down++;

        // 长按-开始
        if (Count_Forward_Key_Down === 2) {
            if (checkPageVideo_YT(page_video) || (page_video = getPageVideo_YT())) {
                is_Forward_Key_Down = true
                Current_Normal_Rate_Forward = page_video.getPlaybackRate();
                page_video.setPlaybackRate(Current_Faster_Rate_Forward);
                console.log(Current_Faster_Rate_Forward + '倍前进加速播放中');
            }
        }
    };
    const Forward_Key_Up_Event_YT = (e) => {
        if (e.keyCode !== Forward_KeyCode) return;
        e.stopPropagation();

        // 单击时
        if (Count_Forward_Key_Down === 1) {
            if (checkPageVideo_YT(page_video) || (page_video = getPageVideo_YT())) {
                page_video.seekToStreamTime(page_video.getCurrentTime() + Add_Time_Forward);
                console.log("前进" + Add_Time_Forward + "秒");
            }
        }

        // 长按-结束
        if (page_video && page_video.playbackRate !== Current_Normal_Rate_Forward) {
            is_Forward_Key_Down = false
            page_video.setPlaybackRate(Current_Normal_Rate_Forward);
            console.log('前进加速播放结束')
        }

        // 计数-重置
        Count_Forward_Key_Down = 0;
    };
    // YT专用 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////








    // 增加 加速前进播放 速度 键按下事件,增加前进加速速度
    const Forward_IncRate_Key_Down_Event = (e) => {
        if (e.keyCode !== Forward_IncRate_KeyCode) return
        e.stopPropagation()

        if (!is_Forward_IncRate_Key_Down) {
            is_Forward_IncRate_Key_Down = true
            Current_Faster_Rate_Forward = Math.min(Current_Faster_Rate_Forward + 1, 10)
            console.log("增加快进速度:" + Current_Faster_Rate_Forward)
            if (is_Forward_Key_Down) {
                page_video.playbackRate = Current_Faster_Rate_Forward
                console.log(Current_Faster_Rate_Forward + '倍前进加速播放中')
            }
        }
    }

    // 增加 加速前进播放 速度 键松开事件
    const Forward_IncRate_Key_Up_Event = (e) => {
        if (e.keyCode !== Forward_IncRate_KeyCode) return
        e.stopPropagation()

        if (is_Forward_IncRate_Key_Down) {
            is_Forward_IncRate_Key_Down = false
        }
    }


    // 减小 加速前进播放 速度 键按下事件,减少前进加速速度
    const Forward_DecRate_Key_Down_Event = (e) => {
        if (e.keyCode !== Forward_DecRate_KeyCode) return
        e.stopPropagation()

        if (!is_Forward_DecRate_Key_Down) {
            is_Forward_DecRate_Key_Down = true
            Current_Faster_Rate_Forward = Math.max(Current_Faster_Rate_Forward - 1, 2)
            console.log("减少快进速度:" + Current_Faster_Rate_Forward)
            if (is_Forward_Key_Down) {
                page_video.playbackRate = Current_Faster_Rate_Forward
                console.log(Current_Faster_Rate_Forward + '倍前进加速播放中')
            }
        }
    }
    // 减小 加速前进播放 速度 键松开事件
    const Forward_DecRate_Key_Up_Event = (e) => {
        if (e.keyCode !== Forward_DecRate_KeyCode) return
        e.stopPropagation()

        if (is_Forward_DecRate_Key_Down) {
            is_Forward_DecRate_Key_Down = false
        }
    }


    // 重置 正常播放 速度 和 加速前进播放 速度 键松开事件,重置速度
    const Forward_ResetRate_Key_Up_Event = (e) => {
        if (e.keyCode !== Forward_ResetRate_KeyCode) return
        e.stopPropagation()

        Current_Normal_Rate_Forward = Init_Normal_Rate_Forward
        Current_Faster_Rate_Forward = Init_Faster_Rate_Forward
        if (is_Forward_Key_Down) {
            page_video.playbackRate = Current_Faster_Rate_Forward
            console.log(Current_Faster_Rate_Forward + '倍前进加速播放中')
        }
        else {
            page_video.playbackRate = Init_Normal_Rate_Forward
        }
        console.log("重置前进设置: 正常=" + Init_Normal_Rate_Forward + ", 快速=" + Init_Faster_Rate_Forward)
    }

/*
.............####.##....##.####.########.####....###....########.########
..............##..###...##..##.....##.....##....##.##......##....##......
..............##..####..##..##.....##.....##...##...##.....##....##......
..............##..##.##.##..##.....##.....##..##.....##....##....######..
..............##..##..####..##.....##.....##..#########....##....##......
..............##..##...###..##.....##.....##..##.....##....##....##......
.............####.##....##.####....##....####.##.....##....##....########
*/
    init()
})();