Skip to content

Instantly share code, notes, and snippets.

@f13end
Created October 22, 2025 14:08
Show Gist options
  • Save f13end/5b159799dd577171185486173f9156ad to your computer and use it in GitHub Desktop.
Save f13end/5b159799dd577171185486173f9156ad to your computer and use it in GitHub Desktop.
Automatically adjust YouTube playback speed based on video type (music vs normal)
// ==UserScript==
// @name YouTube Auto Speed Adjuster
// @namespace https://github.com/f13end
// @version 1.0
// @description Automatically adjust YouTube playback speed based on video type (music vs normal)
// @author F13END
// @homepageURL https://github.com/f13end
// @match https://www.youtube.com/*
// @grant none
// ==/UserScript==
(function () {
'use strict';
const NORMAL_SPEED = 2.0;
const MUSIC_SPEED = 1.0;
const MUSIC_KEYWORDS = [
"official music video",
"official video",
"lyrics",
"song",
"mix",
"audio",
"remix",
"album",
"Dj",
"single",
"music",
"track"
];
function isMusicVideo(title, channel) {
const lowerTitle = (title || "").toLowerCase();
const lowerChannel = (channel || "").toLowerCase();
if (MUSIC_KEYWORDS.some(keyword => lowerTitle.includes(keyword))) return true;
if (lowerChannel.includes("music")) return true;
return false;
}
function setPlaybackSpeed(video, speed) {
if (video && Math.abs(video.playbackRate - speed) > 0.001) {
video.playbackRate = speed;
console.log(`YouTube Auto Speed (f13end): ${speed}x applied`);
}
}
function getTitleElement() {
return document.querySelector('h1.title yt-formatted-string') || document.querySelector('#container h1');
}
function getChannelElement() {
return document.querySelector('#meta-contents ytd-channel-name a') || document.querySelector('#text-container yt-formatted-string');
}
function checkAndSetSpeed() {
const video = document.querySelector('video');
const titleEl = getTitleElement();
const channelEl = getChannelElement();
if (!video) return;
const title = titleEl ? (titleEl.textContent || "") : "";
const channel = channelEl ? (channelEl.textContent || "") : "";
const speed = isMusicVideo(title, channel) ? MUSIC_SPEED : NORMAL_SPEED;
setPlaybackSpeed(video, speed);
}
let lastUrl = location.href;
const urlObserver = new MutationObserver(() => {
const currentUrl = location.href;
if (currentUrl !== lastUrl) {
lastUrl = currentUrl;
setTimeout(checkAndSetSpeed, 1200);
setTimeout(checkAndSetSpeed, 2400);
setTimeout(checkAndSetSpeed, 4000);
}
});
urlObserver.observe(document.body, { childList: true, subtree: true });
const videoListObserver = new MutationObserver(() => checkAndSetSpeed());
videoListObserver.observe(document, { childList: true, subtree: true });
window.addEventListener('load', () => setTimeout(checkAndSetSpeed, 1000));
window.addEventListener('yt-navigate-finish', () => setTimeout(checkAndSetSpeed, 1000));
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment