Greasy Fork

✅✅✅✅✅✅✅✅✅网页视频加速器刷课时万能视频自动播放加速专业技术人员继续教育公需课专业课✅✅✅✅✅✅✅✅✅✅✅

在网页左侧中间悬浮一个红色透明小球,点击后可输入视频加速倍速(最高16倍),记住设置并应用,dai xue 加微:qgjxjy3

// ==UserScript==
// @name         ✅✅✅✅✅✅✅✅✅网页视频加速器刷课时万能视频自动播放加速专业技术人员继续教育公需课专业课✅✅✅✅✅✅✅✅✅✅✅
// @namespace    http://tampermonkey.net/
// @version      1.2
// @description  在网页左侧中间悬浮一个红色透明小球,点击后可输入视频加速倍速(最高16倍),记住设置并应用,dai xue 加微:qgjxjy3
// @author       yelo
// @license      MIT
// @match        *://*/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// ==/UserScript==

(function() {
    'use strict';

    let speedFactor = GM_getValue('videoSpeed', 1.0); // 默认速度为1.0
    const maxSpeed = 16.0;

    // 创建悬浮小球
    const speedButton = document.createElement('div');
    speedButton.id = 'speedButton';
    speedButton.textContent = '加速器';
    document.body.appendChild(speedButton);

    // 创建输入框和确认按钮
    const inputContainer = document.createElement('div');
    inputContainer.id = 'speedInputContainer';
    const speedInput = document.createElement('input');
    speedInput.type = 'number';
    speedInput.min = '1';
    speedInput.max = maxSpeed.toString();
    speedInput.value = speedFactor.toString();
    const confirmButton = document.createElement('button');
    confirmButton.textContent = '确认';
    inputContainer.appendChild(speedInput);
    inputContainer.appendChild(confirmButton);
    document.body.appendChild(inputContainer);
    inputContainer.style.display = 'none'; // 初始隐藏输入框

    // 样式
    GM_addStyle(`
        #speedButton {
            position: fixed;
            top: 50%;
            left: 20px; /* 修改为左侧 */
            transform: translateY(-50%); /* 仅垂直居中 */
            background-color: rgba(255, 0, 0, 0.5);
            color: white;
            border-radius: 50%;
            width: 80px;
            height: 80px;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 14px;
            cursor: pointer;
            z-index: 9999;
        }
        #speedInputContainer {
            position: fixed;
            top: calc(50% + 50px);
            left: 20px; /* 与小球左侧对齐 */
            transform: translateY(-50%); /* 仅垂直方向调整 */
            background-color: white;
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 5px;
            z-index: 10000;
            display: flex;
            gap: 5px;
        }
        #speedInputContainer input {
            width: 60px;
            text-align: center;
        }
    `);

    
    function applySpeed(speed) {
        const videos = document.querySelectorAll('video');
        videos.forEach(video => {
            try {
                video.playbackRate = speed;
            } catch (error) {
                console.error("设置视频速度失败:", error, video);
            }
        });
    }

    
    speedButton.addEventListener('click', () => {
        inputContainer.style.display = 'flex';
    });

    // 点击确认按钮设置视频速度
    confirmButton.addEventListener('click', () => {
        const newSpeed = parseFloat(speedInput.value);
        if (!isNaN(newSpeed) && newSpeed >= 1 && newSpeed <= maxSpeed) {
            speedFactor = newSpeed;
            GM_setValue('videoSpeed', speedFactor);
            applySpeed(speedFactor);
            inputContainer.style.display = 'none';
        } else {
            alert(`请输入 1 到 ${maxSpeed} 之间的有效数字`);
            speedInput.value = speedFactor.toString(); // 恢复上次的有效值
        }
    });

   
    applySpeed(speedFactor);

    
    const observer = new MutationObserver((mutationsList) => {
        for (const mutation of mutationsList) {
            if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
                mutation.addedNodes.forEach(node => {
                    if (node.nodeName === 'VIDEO') {
                        try {
                            node.playbackRate = speedFactor;
                        } catch (error) {
                            console.error("设置新视频速度失败:", error, node);
                        }
                    } else if (node.querySelectorAll) {
                        node.querySelectorAll('video').forEach(video => {
                            try {
                                video.playbackRate = speedFactor;
                            } catch (error) {
                                console.error("设置子元素视频速度失败:", error, video, node);
                            }
                        });
                    }
                });
            }
        }
    });

    observer.observe(document.body, { childList: true, subtree: true });

    setInterval(() => {
        applySpeed(speedFactor);
    }, 5000); 

})();