Skip to content

Instantly share code, notes, and snippets.

@1v
Last active November 12, 2025 15:17
Show Gist options
  • Select an option

  • Save 1v/e3ea8c0d4e33c04f893944348ac8fbc8 to your computer and use it in GitHub Desktop.

Select an option

Save 1v/e3ea8c0d4e33c04f893944348ac8fbc8 to your computer and use it in GitHub Desktop.
Minimal Tampermonkey userscript to increase YouTube maximum playback speed above 2× and override default Shift + > / < shortcuts
// ==UserScript==
// @name YouTube unlimited speed keys with tooltip & session speed memory
// @match https://www.youtube.com/*
// @grant none
// ==/UserScript==
(function () {
"use strict"
const STEP = 0.25
const MIN_SPEED = 0.25
const MAX_SPEED = 10.0
const TOOLTIP_DURATION = 1000 // milliseconds
let lastSpeed = 1.0 // stored only in memory, resets on new tab
// Create a tooltip div
const tooltip = document.createElement("div")
tooltip.style.position = "fixed"
tooltip.style.top = "10px"
tooltip.style.left = "10px"
tooltip.style.padding = "4px 8px"
tooltip.style.backgroundColor = "#f0f0f0"
tooltip.style.color = "#000"
tooltip.style.border = "1px solid #888"
tooltip.style.borderRadius = "4px"
tooltip.style.fontFamily = "Segoe UI, Tahoma, sans-serif"
tooltip.style.fontSize = "14px"
tooltip.style.boxShadow = "2px 2px 6px rgba(0,0,0,0.2)"
tooltip.style.zIndex = 9999
tooltip.style.opacity = "0"
tooltip.style.transition = "opacity 0.3s"
document.body.appendChild(tooltip)
let tooltipTimeout
function showTooltip(text) {
tooltip.textContent = text
tooltip.style.opacity = "1"
clearTimeout(tooltipTimeout)
tooltipTimeout = setTimeout(() => {
tooltip.style.opacity = "0"
}, TOOLTIP_DURATION)
}
function applyLastSpeed() {
const video = document.querySelector("video")
if (video && video.playbackRate !== lastSpeed) {
video.playbackRate = lastSpeed
showTooltip(`${lastSpeed.toFixed(2)}x`)
}
}
document.addEventListener("keydown", (e) => {
if (!e.shiftKey) return
const isIncrease = e.code === "Period"
const isDecrease = e.code === "Comma"
if (!isIncrease && !isDecrease) return
const video = document.querySelector("video")
if (!video) return
e.stopImmediatePropagation()
e.preventDefault()
let newRate = video.playbackRate + (isIncrease ? STEP : -STEP)
newRate = Math.min(Math.max(newRate, MIN_SPEED), MAX_SPEED)
video.playbackRate = newRate
lastSpeed = newRate
showTooltip(`${newRate.toFixed(2)}x`)
}, true)
// Detect internal YouTube navigation (same-tab next video)
window.addEventListener("yt-navigate-finish", () => {
setTimeout(applyLastSpeed, 1000)
})
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment