Greasy Fork is available in English.
Set a default playback rate for YouTube videos.
// ==UserScript== // @name YoutubeDefaultSpeed // @namespace youtubedefaultspeed // @version 1.1.1 // @author splttingatms // @homepage https://github.com/splttingatms/YouTubeDefaultSpeed // @description Set a default playback rate for YouTube videos. // @match http*://*.youtube.com/* // @grant GM_getValue // @grant GM_setValue // @run-at document-idle // @noframes // ==/UserScript== (function () { 'use strict'; var RATE_OPTIONS = ["0.25", "0.5", "1", "1.25", "1.5", "2", "2.2", "2.5", "2.7", "3"]; var RETRY_DELAY_IN_MS = 100; function getElement(query, callback) { var element = document.querySelector(query); if (element === null) { // null possible if element not loaded yet, retry with delay window.setTimeout(function () { getElement(query, callback); }, RETRY_DELAY_IN_MS); } else { callback(element); } } function setPlaybackRate(rate) { // video element can force unofficial playback rates getElement("video", function (video) { video.playbackRate = rate; }); // movie_player div controls the displayed "Speed" in player menu // note: does not show values beyond official list getElement("#movie_player", function (player) { player.setPlaybackRate(rate); }); } function setPlaybackRateToPreference() { var preferredRate = GM_getValue("playbackRate", 1); // default to 1 if not set yet setPlaybackRate(preferredRate); } function onElementSourceUpdate(target, callback) { var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; var observer = new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { callback(); }); }); observer.observe(target, {attributes: true, attributeFilter: ["src"]}); } function handleRateButtonClick(rate) { GM_setValue("playbackRate", rate); setPlaybackRate(rate); } function injectButtons() { var head = document.getElementById("yt-masthead-user"); var form = document.createElement("form"); RATE_OPTIONS.forEach(function (rate) { var input = document.createElement("input"); input.type = "radio"; input.name = "playbackRate"; input.id = "playbackRate" + rate; input.onclick = function () { handleRateButtonClick(rate); }; input.checked = (rate === GM_getValue("playbackRate", 1)); var label = document.createElement("label"); label.htmlFor = "playbackRate" + rate; label.innerHTML = rate; label.style = "margin-right: 5px"; form.appendChild(input); form.appendChild(label); }); head.appendChild(form); } function main() { injectButtons(); setPlaybackRateToPreference(); // YouTube uses AJAX so monitor element for video changes getElement("video", function (video) { onElementSourceUpdate(video, function () { setPlaybackRateToPreference(); }); }); } main(); })();