Skip to content

Instantly share code, notes, and snippets.

@wynemo
Last active June 16, 2023 17:12
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wynemo/4536bf7d7f436122f5d2009b437f43b7 to your computer and use it in GitHub Desktop.
Save wynemo/4536bf7d7f436122f5d2009b437f43b7 to your computer and use it in GitHub Desktop.
Youtube Advanced Speed Controller
// ==UserScript==
// @name Youtube Advanced Speed Controller
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Allows you to play youtube videos from 0 to 16 times normal speed
// @author Ehren Julien-Neitzert
// @match https://www.youtube.com/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
var old_url = '';
function gecChannel() {
var xpath = '//*[@id="text"]/a';
var result = document.evaluate(
xpath,
document,
null,
XPathResult.FIRST_ORDERED_NODE_TYPE,
null
);
var node = result.singleNodeValue;
var href = node.getAttribute("href");
return href;
}
//sets the rate of a youtube video
function setRate(n) {
document.getElementsByClassName("html5-video-container")[0]
.getElementsByClassName("video-stream html5-main-video")[0]
.playbackRate = n;
}
function _get_rate() {
return document.getElementsByClassName("html5-video-container")[0]
.getElementsByClassName("video-stream html5-main-video")[0]
.playbackRate;
}
//gets the current rate of a youtube video
function getRate() {
var channel = gecChannel();
console.log('channel is ', channel);
if (channel === '/@FQQ' || channel === '/@pingchuan') {
return 1.75;
} else {
return 1;
}
return _get_rate();
}
//determines if theres a video bar to inject onto
function hasVideo() {
return document.getElementsByClassName("ytp-right-controls").length != 0;
}
//injects the speed controller
function injectController() {
console.log('here injectController');
//create speed controller
var i = document.createElement('input');
i.style = "width: 20%; height: 70%; position: relative; bottom: 37%; background-Color: transparent; color: white; border-Color: transparent;";
i.id = 'spdctrl';
i.title = 'Playback Rate';
i.style.fontSize = '100%';
i.type = 'number';
i.value = getRate();
i.step = 0.1;
i.max = 16;
i.min = 0;
i.onchange = function() {
var s = i.value;
setRate(s);
console.log('value change set rate to', i.value);
};
//make the standard speed controls change the new speed controller
document.getElementsByTagName('video')[0].onratechange = function() {
if (document.activeElement != i) { //only change i's value if its not being focused (ie, just clicked on)
i.value = _get_rate();
console.log('84 rate to', i.value);
}
};
//put speed controller in youtube bar
toolbar = document.getElementsByClassName("ytp-right-controls")[0];
toolbar.prepend(i);
console.log('injectController set rate to', i.value);
setRate(i.value);
}
//every fraction of a second check if the controller's injected and if theres a video
//I have to do this because I don't think theres an easy way to detect the crazy history rewrite stuff that they do to give the illusion of you loading a page when you're actually not
window.setInterval(function(){
var controller = document.getElementById('spdctrl');
if (controller === null && hasVideo()) {
injectController();
}
var current_url = window.location.href;
if (old_url === '') {
old_url = current_url;
}
console.log('current', current_url, old_url);
if (current_url !== old_url) {
old_url = current_url;
setTimeout(() => {
var rate = getRate();
console.log("Delayed for 1.5 second.");
console.log('url change set rate to', rate);
setRate(rate);
}, "1500");
}
}, 300);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment