Greasy Fork

视频倍速工具

除youtube以外按c加速,按x减速,按z复位,youtube按v加速。

当前为 2023-01-19 提交的版本,查看 最新版本

// ==UserScript==
// @name         视频倍速工具
// @namespace    http://tampermonkey.net/
// @version      0.1.0
// @description  除youtube以外按c加速,按x减速,按z复位,youtube按v加速。
// @author       call duck
// @match        *://*/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=bilibili.com
// @grant        none
// @run-at document-end
// @license MIT
// ==/UserScript==

// 使用方法:除youtube以外按c加速,按x减速,按z复位,youtube按v加速。

(function () {
    'use strict';
    if (window.innerWidth < 100) {
        return
    }
    let video
    let speed = 1

    video = document.getElementsByTagName('video')[0]

    new Promise((res) => {
        if (!video) {
            let count = 0
            const maxCount = 3
            function getVideo() {
                setTimeout(() => {
                    video = document.getElementsByTagName('video')[0]
                    count++
                    if (!video && count < maxCount) {
                        getVideo()
                    } else {
                        res(video)
                    }
                }, 1000);
            }
            getVideo()
        } else {
            res(video)
        }
    }).then((video) => {
        handleVideo(video)
    })


/*     document.addEventListener('click', (e) => {
        console.log(e.target)
        videos = Array.from(document.getElementsByTagName('video'))
        for (let i = 0; i < videos.length; i++) {
            const v = videos[i];
            handleVideo(v)
        }
    }) */

    function findVideoInDom(dom) {
        var v = dom.getElementsByTagName('video')[0]
        if (!v && !dom.shadowRoot) {
            return null
        }
        if (!v && dom.shadowRoot) {
            findVideoInDom(dom.shadowRoot)
        }
    }

    function handleVideo(video) {
        if (video && video.tagName && video.tagName.toLowerCase() === 'video') {
            const step = 0.05
            speed = video.playbackRate

            video.addEventListener('ratechange', function () {
                speed = video.playbackRate
            })
            window.addEventListener('keypress', function (e) {
                if (this.document.activeElement.tagName.toLowerCase() === 'input') {
                    return
                }
                if (e.key.toLowerCase() === "c") {
                    if (this.location.hostname === 'www.youtube.com') {
                        return
                    }
                    speed = Math.round((speed + step) * 100) / 100
                    video.playbackRate = speed
                    notify(video.playbackRate)
                }
                // youtube单独处理。
                if (this.location.hostname === 'www.youtube.com' && e.key.toLowerCase() === "v") {
                    speed = Math.round((speed + step) * 100) / 100
                    video.playbackRate = speed
                    notify(video.playbackRate)
                }
                if (e.key.toLowerCase() === "x") {
                    speed = Math.round((speed - step) * 100) / 100
                    video.playbackRate = speed
                    notify(video.playbackRate)
                }
                if (e.key.toLowerCase() === "z") {
                    speed = 1
                    video.playbackRate = speed
                    notify(video.playbackRate)
                }
            })

            video.addEventListener('play', () => {
                video.playbackRate = speed
            });
        }
    }

    function notify(msg) {
        const videoWrap = video.parentElement
        const className = 'edbe85b469d47a8833b84e259864e33'
        const box = document.createElement('div')
        box.className = className
        box.style.background = '#333'
        box.style.color = '#fff'
        box.style.padding = '8px 20px'
        box.style.position = 'fixed'
        box.style.margin = "auto"
        box.style.left = '50%'
        box.style.top = '30px'
        box.style.transform = "translateX(-50%)";
        box.style.borderRadius = "5px"
        box.style.zIndex = '10000'
        box.style.fontSize = '1rem'
        box.innerHTML = msg
        const oldBox = document.querySelectorAll('.' + className)
        if (oldBox.length) {
            oldBox.forEach(b => {
                b.remove()
            });
        }
        if (document.fullscreenElement) {
            videoWrap.appendChild(box)
        } else {
            document.body.appendChild(box)
        }
        setTimeout(() => {
            box.remove()
        }, 2000);
    }
})();