YouTube Speed Controller 12x

Control YouTube video playback speed up to 12x

Size

7.0 KB

Version

1.0.1

Created

Dec 24, 2025

Updated

28 days ago

1// ==UserScript==
2// @name		YouTube Speed Controller 12x
3// @description		Control YouTube video playback speed up to 12x
4// @version		1.0.1
5// @match		https://*.youtube.com/*
6// @icon		https://www.youtube.com/s/desktop/a3c20ab4/img/favicon_32x32.png
7// ==/UserScript==
8(function() {
9    'use strict';
10
11    console.log('YouTube Speed Controller 12x initialized');
12
13    // Speed options from 0.25x to 12x
14    const speedOptions = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 2.5, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
15
16    function createSpeedControl() {
17        console.log('Creating speed control UI');
18        
19        // Remove existing control if present
20        const existingControl = document.getElementById('custom-speed-control');
21        if (existingControl) {
22            existingControl.remove();
23        }
24
25        // Find the video element
26        const video = document.querySelector('video');
27        if (!video) {
28            console.log('Video element not found');
29            return;
30        }
31
32        // Create speed control container
33        const speedControl = document.createElement('div');
34        speedControl.id = 'custom-speed-control';
35        speedControl.style.cssText = `
36            position: fixed;
37            bottom: 100px;
38            right: 20px;
39            background: rgba(0, 0, 0, 0.9);
40            color: white;
41            padding: 15px;
42            border-radius: 8px;
43            z-index: 9999;
44            font-family: 'Roboto', Arial, sans-serif;
45            font-size: 14px;
46            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
47            min-width: 200px;
48        `;
49
50        // Create title
51        const title = document.createElement('div');
52        title.textContent = 'Playback Speed';
53        title.style.cssText = `
54            font-weight: bold;
55            margin-bottom: 10px;
56            font-size: 16px;
57            text-align: center;
58        `;
59        speedControl.appendChild(title);
60
61        // Create current speed display
62        const currentSpeedDisplay = document.createElement('div');
63        currentSpeedDisplay.id = 'current-speed-display';
64        currentSpeedDisplay.textContent = `Current: ${video.playbackRate}x`;
65        currentSpeedDisplay.style.cssText = `
66            text-align: center;
67            margin-bottom: 10px;
68            color: #3ea6ff;
69            font-weight: bold;
70        `;
71        speedControl.appendChild(currentSpeedDisplay);
72
73        // Create speed buttons container
74        const buttonsContainer = document.createElement('div');
75        buttonsContainer.style.cssText = `
76            display: grid;
77            grid-template-columns: repeat(3, 1fr);
78            gap: 5px;
79            max-height: 300px;
80            overflow-y: auto;
81        `;
82
83        // Create buttons for each speed option
84        speedOptions.forEach(speed => {
85            const button = document.createElement('button');
86            button.textContent = `${speed}x`;
87            button.style.cssText = `
88                background: #3ea6ff;
89                color: white;
90                border: none;
91                padding: 8px 12px;
92                border-radius: 4px;
93                cursor: pointer;
94                font-size: 13px;
95                font-weight: 500;
96                transition: all 0.2s;
97            `;
98
99            // Highlight current speed
100            if (video.playbackRate === speed) {
101                button.style.background = '#ff3e3e';
102            }
103
104            button.addEventListener('mouseenter', () => {
105                if (video.playbackRate !== speed) {
106                    button.style.background = '#5ab3ff';
107                }
108            });
109
110            button.addEventListener('mouseleave', () => {
111                if (video.playbackRate !== speed) {
112                    button.style.background = '#3ea6ff';
113                }
114            });
115
116            button.addEventListener('click', () => {
117                video.playbackRate = speed;
118                currentSpeedDisplay.textContent = `Current: ${speed}x`;
119                console.log(`Speed changed to ${speed}x`);
120                
121                // Update button styles
122                buttonsContainer.querySelectorAll('button').forEach(btn => {
123                    btn.style.background = '#3ea6ff';
124                });
125                button.style.background = '#ff3e3e';
126            });
127
128            buttonsContainer.appendChild(button);
129        });
130
131        speedControl.appendChild(buttonsContainer);
132
133        // Add close button
134        const closeButton = document.createElement('button');
135        closeButton.textContent = '×';
136        closeButton.style.cssText = `
137            position: absolute;
138            top: 5px;
139            right: 5px;
140            background: transparent;
141            color: white;
142            border: none;
143            font-size: 24px;
144            cursor: pointer;
145            padding: 0;
146            width: 25px;
147            height: 25px;
148            line-height: 20px;
149        `;
150        closeButton.addEventListener('click', () => {
151            speedControl.style.display = 'none';
152        });
153        speedControl.appendChild(closeButton);
154
155        // Add toggle button
156        const toggleButton = document.createElement('button');
157        toggleButton.id = 'speed-control-toggle';
158        toggleButton.textContent = '⚡';
159        toggleButton.title = 'Speed Control';
160        toggleButton.style.cssText = `
161            position: fixed;
162            bottom: 100px;
163            right: 20px;
164            background: rgba(0, 0, 0, 0.9);
165            color: white;
166            border: none;
167            width: 50px;
168            height: 50px;
169            border-radius: 50%;
170            cursor: pointer;
171            font-size: 24px;
172            z-index: 9998;
173            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
174            display: none;
175        `;
176        toggleButton.addEventListener('click', () => {
177            speedControl.style.display = 'block';
178            toggleButton.style.display = 'none';
179        });
180
181        document.body.appendChild(speedControl);
182        document.body.appendChild(toggleButton);
183
184        console.log('Speed control UI created successfully');
185    }
186
187    // Wait for video element to be available
188    function waitForVideo() {
189        const video = document.querySelector('video');
190        if (video) {
191            console.log('Video element found');
192            createSpeedControl();
193        } else {
194            console.log('Waiting for video element...');
195            setTimeout(waitForVideo, 1000);
196        }
197    }
198
199    // Initialize when page loads
200    if (document.readyState === 'loading') {
201        document.addEventListener('DOMContentLoaded', waitForVideo);
202    } else {
203        waitForVideo();
204    }
205
206    // Re-create control on navigation (YouTube is a SPA)
207    let lastUrl = location.href;
208    new MutationObserver(() => {
209        const currentUrl = location.href;
210        if (currentUrl !== lastUrl) {
211            lastUrl = currentUrl;
212            console.log('URL changed, re-initializing speed control');
213            setTimeout(waitForVideo, 2000);
214        }
215    }).observe(document.body, { childList: true, subtree: true });
216
217})();
YouTube Speed Controller 12x | Robomonkey