Skip to content

Instantly share code, notes, and snippets.

@wynemo
Last active June 16, 2023 17:12
Show Gist options
  • Select an option

  • Save wynemo/4536bf7d7f436122f5d2009b437f43b7 to your computer and use it in GitHub Desktop.

Select an option

Save wynemo/4536bf7d7f436122f5d2009b437f43b7 to your computer and use it in GitHub Desktop.

Revisions

  1. wynemo renamed this gist May 21, 2023. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  2. wynemo created this gist May 21, 2023.
    124 changes: 124 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,124 @@
    // ==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);

    })();