Youtube Player Speed Slider

Add Speed Slider to Youtube Player Settings

As of 2016-11-23. See the latest version.

// ==UserScript==
// @name         Youtube Player Speed Slider
// @namespace    youtube_player_speed_slider
// @version      0.1.2
// @description  Add Speed Slider to Youtube Player Settings
// @author       Łukasz and Witold
// @match        https://*.youtube.com/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    var YT_F = {};

    YT_F.option = {
        menu:null,
        speedMenu: null,
        label:null,
        menuClass : "ytp-menuitem",
        labelText : 'Speed',
        timeoutBuild: 500,
        timeoutRemove: 2000,
        timeoutTry: 1000,
    };

    YT_F.new = function(tag, option){
        var element = document.createElement(tag);
        for(var param in option){
            element[param] = option[param];
        }
        return element;
    };

    YT_F.get = function(tselector, all){
        all = all || false;
        var type = tselector.substring(0,1);
        var selector = tselector.substring(1);
        if(type == "#"){
            return document.getElementById(selector);
        }
        else if(type == "."){
            var elements = document.getElementsByClassName(selector);
            if(all){
                return elements;
            }
            else{
                return elements.length ? elements[0] : null;
            }
        }
    };

    YT_F.build = function() {
        YT_F.option.menu = YT_F.get('.ytp-panel-menu');
        if(YT_F.option.menu !== null){
            YT_F.option.menu.appendChild(YT_F.buildSpeedMenu());

            setTimeout(YT_F.removeDefaultSpeedMenu, YT_F.option.timeoutRemove);
            setTimeout(YT_F.annotationsSwitchOff, YT_F.option.timeoutRemove);
        }
        else{
            setTimeout(YT_F.build, YT_F.option.timeoutBuild);
        }
    };

    YT_F.buildSpeedMenu = function(){
        YT_F.option.speedMenu = YT_F.new('div', {'className':'ytp-menuitem'});

	    YT_F.option.speedMenu.label = YT_F.new('div', {'className':'ytp-menuitem-label', 'innerHTML':'<b>Speed: 1</b>'});
	    var right = YT_F.new('div', {'className':'ytp-menuitem-content'});
	    var range = YT_F.new('input', {'className':'', 'type':'range', 'min':0.5, 'max':4, 'step':0.1, 'value':1});
        document.addEventListener('change', YT_F.onchange);
        document.addEventListener('input', YT_F.updateLabel);

        right.appendChild(range);
        YT_F.option.speedMenu.appendChild(YT_F.option.speedMenu.label);
        YT_F.option.speedMenu.appendChild(right);
        return YT_F.option.speedMenu;
    };

    YT_F.updateLabel = function(event){
        YT_F.option.speedMenu.label.innerHTML = YT_F.option.labelText + ": " + event.target.value;
    };

    YT_F.onchange = function(event){
        YT_F.updatePlayerSpeed(event.target.value);
    };

    YT_F.updatePlayerSpeed= function(value){
        YT_F.get('.html5-main-video').playbackRate = value;
    };

    YT_F.annotationsSwitchOff = function(){
        var settings_button = YT_F.get(".ytp-settings-button");
        var all_labels = YT_F.get(".ytp-menuitem-label", true);
        settings_button.click();
        settings_button.click();

        for (var i = 0; i < all_labels.length; i++) {
            if (all_labels[i].innerHTML == "Annotations" || all_labels[i].innerHTML == "Adnotacje"){
                if(all_labels[i].parentNode.getAttribute("aria-checked") == "true"){
                    (all_labels[i].parentNode.click());
                }
                return true;
            }
        }
        return false;
    };

    YT_F.tryAnnotationsSwitchOff = function(){
        if(!YT_F.annotationsSwitchOff()){
            setTimeout(YT_F.tryAnnotationsSwitchOff, YT_F.option.timeoutTry);
        }
    };

    YT_F.removeDefaultSpeedMenu = function(){
        var settings_button = YT_F.get(".ytp-settings-button");
        var all_labels = YT_F.get(".ytp-menuitem-label", true);
        settings_button.click();
        settings_button.click();
        for (var i = 0; i < all_labels.length; i++) {
            if (all_labels[i].innerHTML == "Speed" || all_labels[i].innerHTML == "Szybkość"){
                YT_F.option.labelText = all_labels[i].innerHTML;
                all_labels[i].parentNode.style.display = 'none';
            }
        }
    };

    YT_F.build();
    document.addEventListener("spfdone", function(){setTimeout(YT_F.tryAnnotationsSwitchOff, YT_F.option.timeoutRemove);});
})();