Modern Speed Controller - Youtube/Music

—Hexation—

Member
Joined
September 28, 2025
Messages
6
Reaction score
0
Points
1
JavaScript:
// ==UserScript==
// @name         YouTube Minimalistic Speed Controller
// @namespace    http://tampermonkey.net/
// @version      2.2.2
// @description  A self-contained, minimalistic speed controller that collapses after 5s of inactivity. Bounces on expand/collapse. Double-click speed to reset.
// @author       Gemini
// @match        *://*.youtube.com/*
// @exclude      *://music.youtube.com/*
// @exclude      *://studio.youtube.com/*
// @grant        none
// @run-at       document-idle
// ==/UserScript==

(function() {
    'use strict';

    // --- Configuration ---
    let userPreferredContentSpeed = 1.0;
    const MIN_CONTENT_SPEED = 0.1;
    const MAX_CONTENT_SPEED = 15.0;
    const SPEED_STEP = 0.1;
    const RESET_SPEED = 1.0;
    const INACTIVITY_TIMEOUT = 5000;

    // --- Global Variables ---
    let speedControllerElement, speedDisplayElement;
    let speedEnforceIntervalId, collapseTimer;
    let isCollapsed = false;

    // --- CSS Injection for Animations ---
    function injectCss() {
        document.getElementById('yt-speed-controller-styles')?.remove();
        const css = `
            #yt-speed-controller {
                height: 36px; /* MODIFIED: Slightly taller original height */
                width: 145px;
                padding: 5px 15px;
                transition: width 0.6s cubic-bezier(0.34, 1.56, 0.64, 1),
                            padding 0.6s cubic-bezier(0.34, 1.56, 0.64, 1),
                            height 0.6s cubic-bezier(0.34, 1.56, 0.64, 1),
                            opacity 0.3s ease;
            }
            #yt-speed-controller.collapsed {
                height: 27px; /* MODIFIED: 75% of original height */
                width: 72px;  /* MODIFIED: 50% of original width */
                align-items: flex-end; /* NEW: Aligns content to the bottom when collapsed */
            }
            #yt-speed-controller .yt-controller-inner-wrapper {
                opacity: 1;
                transition: opacity 0.2s 0.1s ease-in-out;
            }
            #yt-speed-controller.collapsed .yt-controller-inner-wrapper {
                opacity: 0;
                transition: opacity 0.1s ease-in-out;
            }
            #yt-speed-controller .yt-collapsed-indicator {
                opacity: 0;
                padding-bottom: 2px; /* Adjust vertical position of the dash */
                transition: opacity 0.1s ease-in-out;
            }
            #yt-speed-controller.collapsed .yt-collapsed-indicator {
                opacity: 1;
                transition: opacity 0.2s 0.1s ease-in-out;
            }
        `;
        const styleElement = document.createElement('style');
        styleElement.id = 'yt-speed-controller-styles';
        styleElement.textContent = css;
        document.head.appendChild(styleElement);
    }

    // --- Animation & State Management via CSS classes ---
    function expandController() {
        if (!isCollapsed || !speedControllerElement) return;
        isCollapsed = false;
        speedControllerElement.classList.remove('collapsed');
    }

    function collapseController() {
        if (isCollapsed || (speedControllerElement && speedControllerElement.matches(':hover'))) return;
        isCollapsed = true;
        speedControllerElement.classList.add('collapsed');
    }

    // --- UI Creation & Logic ---
    function getOrCreateSpeedController() {
        if (document.getElementById('yt-speed-controller')) return;

        speedControllerElement = document.createElement('div');
        speedControllerElement.id = 'yt-speed-controller';
        Object.assign(speedControllerElement.style, {
            position: 'fixed', bottom: '20px', left: '50%', transform: 'translateX(-50%)',
            backgroundColor: 'rgba(32, 39, 95, 0.5)', color: '#d1c2ea',
            borderRadius: '25px', zIndex: '2147483647',
            fontFamily: 'Arial, sans-serif', display: 'flex', alignItems: 'center', justifyContent: 'center',
            userSelect: 'none', backdropFilter: 'blur(10px)', webkitBackdropFilter: 'blur(10px)',
            border: '1px solid rgba(209, 194, 234, 0.2)',
            opacity: '0', overflow: 'hidden', boxSizing: 'border-box'
        });

        const innerWrapper = document.createElement('div');
        innerWrapper.className = 'yt-controller-inner-wrapper';
        Object.assign(innerWrapper.style, { display: 'flex', alignItems: 'center', gap: '10px' });

        const collapsedIndicator = document.createElement('span');
        collapsedIndicator.className = 'yt-collapsed-indicator';
        collapsedIndicator.textContent = '⌬';
        Object.assign(collapsedIndicator.style, { position: 'absolute', fontSize: '15px' });

        const decreaseSpeedButton = document.createElement('button');
        decreaseSpeedButton.textContent = '↼';
        decreaseSpeedButton.title = 'Decrease speed';
        styleControlButton(decreaseSpeedButton);
        decreaseSpeedButton.addEventListener('click', () => changeContentSpeed(-SPEED_STEP));

        speedDisplayElement = document.createElement('span');
        speedDisplayElement.textContent = `${userPreferredContentSpeed.toFixed(2)}x`;
        Object.assign(speedDisplayElement.style, { minWidth: '45px', textAlign: 'center', fontSize: '15px', fontWeight: 'bold', cursor: 'pointer' });
        speedDisplayElement.title = 'Double-click to reset speed to 1.0x';
        speedDisplayElement.addEventListener('dblclick', () => {
            userPreferredContentSpeed = RESET_SPEED;
            speedDisplayElement.textContent = `${userPreferredContentSpeed.toFixed(2)}x`;
            applySpeedToVideo();
        });

        const increaseSpeedButton = document.createElement('button');
        increaseSpeedButton.textContent = '⇀';
        increaseSpeedButton.title = 'Increase speed';
        styleControlButton(increaseSpeedButton);
        increaseSpeedButton.addEventListener('click', () => changeContentSpeed(SPEED_STEP));

        innerWrapper.appendChild(decreaseSpeedButton);
        innerWrapper.appendChild(speedDisplayElement);
        innerWrapper.appendChild(increaseSpeedButton);
        speedControllerElement.appendChild(innerWrapper);
        speedControllerElement.appendChild(collapsedIndicator);
        document.body.appendChild(speedControllerElement);

        speedControllerElement.addEventListener('mouseenter', () => {
            clearTimeout(collapseTimer);
            expandController();
        });
        speedControllerElement.addEventListener('mouseleave', () => {
            collapseTimer = setTimeout(collapseController, INACTIVITY_TIMEOUT);
        });
    }

    function styleControlButton(button) {
        Object.assign(button.style, {
            background: 'transparent', border: 'none', color: '#d1c2ea',
            cursor: 'pointer', padding: '0', fontSize: '20px', lineHeight: '1'
        });
        button.onmouseover = () => button.style.opacity = '0.7';
        button.onmouseout = () => button.style.opacity = '1';
    }

    function changeContentSpeed(delta) {
        let newSpeed = userPreferredContentSpeed + delta;
        newSpeed = Math.max(MIN_CONTENT_SPEED, Math.min(MAX_CONTENT_SPEED, newSpeed));
        userPreferredContentSpeed = parseFloat(newSpeed.toFixed(2));
        if (speedDisplayElement) {
            speedDisplayElement.textContent = `${userPreferredContentSpeed.toFixed(2)}x`;
        }
        applySpeedToVideo();
    }

    function applySpeedToVideo() {
        const videoElement = document.querySelector('.html5-main-video');
        if (videoElement && videoElement.playbackRate !== userPreferredContentSpeed) {
            videoElement.playbackRate = userPreferredContentSpeed;
        }
    }

    function initialize() {
        if (speedEnforceIntervalId) clearInterval(speedEnforceIntervalId);
        let attempts = 0;
        const maxAttempts = 20;

        function tryToStart() {
            attempts++;
            const videoPlayerExists = document.querySelector('#movie_player .html5-main-video');
            if (videoPlayerExists && document.body.contains(videoPlayerExists)) {
                injectCss();
                getOrCreateSpeedController();
                if (speedControllerElement) {
                    speedControllerElement.style.opacity = '1';
                    collapseTimer = setTimeout(collapseController, INACTIVITY_TIMEOUT);
                }
                speedEnforceIntervalId = setInterval(applySpeedToVideo, 500);
            } else if (attempts < maxAttempts) {
                setTimeout(tryToStart, 500);
            }
        }
        setTimeout(tryToStart, 250);
    }

    function cleanup() {
        clearTimeout(collapseTimer);
        if (speedEnforceIntervalId) clearInterval(speedEnforceIntervalId);
        document.getElementById('yt-speed-controller')?.remove();
        document.getElementById('yt-speed-controller-styles')?.remove();
        speedControllerElement = null;
        speedDisplayElement = null;
        isCollapsed = false;
    }

    if (document.readyState === 'complete' || document.readyState === 'interactive') {
        initialize();
    } else {
        window.addEventListener('DOMContentLoaded', initialize, { once: true });
    }
    document.addEventListener('yt-navigate-finish', () => {
        cleanup();
        initialize();
    });

})();

Install using tamperMonkey. Hope you'll like it. Please let me know how I can improve.
 

@Freelancertykm

Member
Joined
September 27, 2025
Messages
25
Reaction score
0
Points
1
I Got Valid Non VBV CCs With Good And Hitting Highly balance and guarantee save Full Info



Good for All online shopping and site

Linkable for cash app and Apple Pay

Booking ticket and buying crypto



Validly 98-99 No verification or proxy needed

NB:All ccs are replaceable/refundable Got Valid Non VBV CCs With Good And Hitting Highly balance and guarantee save Full Info Tele:@Freelancertykmf
 
  • Tags
    modern speed youtube