Giữ chuột trái để tua nhanh video

Nhấp chuột giữa để chuyển đổi tốc độ video và giữ chuột để tăng tốc tạm thời. Chuyển đổi/giữ để tăng tốc video, đánh dấu tốc độ đã chọn bằng ✔ và tự động tải lại trang để áp dụng các thay đổi ngay lập tức. Hỗ trợ các tùy chọn tốc độ cố định như x0.5, x0.75, x1.25, x1.5, x2.0, x3.0 và đặt lại về mặc định x1.0.

目前為 2025-04-29 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Giữ chuột trái để tua nhanh video
// @name:en         Video Speed Controller with Persistent Speed (Auto Reload on Selection)
// @namespace    http://tampermonkey.net/
// @version      1.3
// @description  Nhấp chuột giữa để chuyển đổi tốc độ video và giữ chuột để tăng tốc tạm thời. Chuyển đổi/giữ để tăng tốc video, đánh dấu tốc độ đã chọn bằng ✔ và tự động tải lại trang để áp dụng các thay đổi ngay lập tức. Hỗ trợ các tùy chọn tốc độ cố định như x0.5, x0.75, x1.25, x1.5, x2.0, x3.0 và đặt lại về mặc định x1.0.
// @description:en  Middle click to toggle video speed and hold mouse to temporarily speed up. Toggle/hold to speed up video, mark selected speed with ✔, and reload page automatically to apply changes instantly. Supports persistent speed options like x0.5, x0.75, x1.25, x1.5, x2.0, x3.0, and reset to x1.0 default.
// @author       Hoàng Nam
// @match        *://*/*
// @grant        GM_registerMenuCommand
// @grant        GM_setValue
// @grant        GM_getValue
// @license            MIT2
// ==/UserScript==




(function () {
    'use strict';

    let video = null;
    let indicator = null;
    let holdTimeout = null;
    let isHeld = false;

    const normalSpeed = 1.0;
    const speedOptions = [0.5, 0.75, 1.25, 1.5, 2.0, 3.0];
    let fastSpeed = normalSpeed;

    async function loadStoredSpeed() {
        const stored = await GM_getValue('fastSpeed', normalSpeed);
        fastSpeed = parseFloat(stored);
    }

    async function setStoredSpeed(speed) {
        fastSpeed = speed;
        await GM_setValue('fastSpeed', speed);

        // Reload để áp dụng thay đổi và cập nhật dấu chọn
        location.reload();
    }

    function createIndicator(videoElement) {
        if (indicator) indicator.remove();

        indicator = document.createElement('div');
        indicator.textContent = `x${fastSpeed}`;
        Object.assign(indicator.style, {
            position: 'absolute',
            top: '10px',
            right: '10px',
            backgroundColor: 'rgba(0, 0, 0, 0.7)',
            color: 'white',
            fontSize: '16px',
            fontWeight: 'bold',
            padding: '4px 8px',
            borderRadius: '4px',
            zIndex: 9999,
            display: 'none',
            fontFamily: 'Arial, sans-serif',
            pointerEvents: 'none'
        });

        const container = videoElement.parentElement;
        const style = window.getComputedStyle(container);
        if (style.position === 'static') {
            container.style.position = 'relative';
        }

        container.appendChild(indicator);
    }

    function updateIndicatorText() {
        if (indicator) {
            indicator.textContent = `x${video ? video.playbackRate.toFixed(2) : fastSpeed}`;
        }
    }

    function findAndBindVideo() {
        const found = document.querySelector('video');
        if (found && found !== video) {
            video = found;
            createIndicator(video);

            if (fastSpeed !== normalSpeed) {
                video.playbackRate = fastSpeed;

            }
        }
    }

    function showIndicator() {
        if (indicator) {
            updateIndicatorText();
            indicator.style.display = 'block';
        }
    }

    function hideIndicator() {
        if (indicator) {
            indicator.style.display = 'none';
        }
    }

    function onMouseDown(event) {
        if (!video) return;

        if (event.button === 1) { // Middle click
            if (video.playbackRate === normalSpeed) {
                video.playbackRate = fastSpeed;
                showIndicator();
            } else {
                video.playbackRate = normalSpeed;
                hideIndicator();
            }
            event.preventDefault();
            return;
        }

        holdTimeout = setTimeout(() => {
            video.playbackRate = fastSpeed;
            showIndicator();
            isHeld = true;
        }, 600);
    }

    function onMouseUp() {
        clearTimeout(holdTimeout);
        if (isHeld && video) {
            video.playbackRate = normalSpeed;
            hideIndicator();
            isHeld = false;
        }
    }

    async function setupMenuCommands() {
        const storedSpeed = await GM_getValue('fastSpeed', normalSpeed);

        speedOptions.forEach(speed => {
            const label = speed === storedSpeed
                ? `✔ Set Fast Speed to x${speed}`
                : `Set Fast Speed to x${speed}`;
            GM_registerMenuCommand(label, () => {
                setStoredSpeed(speed);
            });
        });

        const resetLabel = storedSpeed === normalSpeed
            ? '✔ Đặt lại về mặc định (x1.0)'
            : 'Đặt lại về mặc định (x1.0)';
        GM_registerMenuCommand(resetLabel, () => {
            setStoredSpeed(normalSpeed);
        });
    }

    async function init() {
        await loadStoredSpeed();
        setupMenuCommands();

        window.addEventListener('mousedown', onMouseDown);
        window.addEventListener('mouseup', onMouseUp);
        window.addEventListener('mouseout', onMouseUp);

        const observer = new MutationObserver(() => {
            findAndBindVideo();
        });
        observer.observe(document.body, { childList: true, subtree: true });

        findAndBindVideo();
    }

    init();
})();







QingJ © 2025

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