// ==UserScript== // @name netflix-speed // @version 0.6 // @include https://www.netflix.com/* // ==/UserScript== function find_controls() { return new Promise(function(resolve, reject) { var observer = new MutationObserver(function(mutationsList) { mutationsList.forEach(function(mutation) { var nodes = Array.from(mutation.addedNodes); for (var node of nodes) { /* classic ui - black bar at the bottom */ if (node.matches && node.matches('.classic-ui') && node.querySelector('.video-title')) { resolve(node.querySelector('.video-title').previousElementSibling); return; } /* modern ui - play/pause in the middle of the screen */ if (node.matches && node.matches('.AkiraPlayer') && (node.querySelector('.button-nfplayerNextEpisode') || node.querySelector('.button-nfplayerSubtitles'))) { var elem = node.querySelector('.button-nfplayerNextEpisode') || node.querySelector('.button-nfplayerSubtitles'); resolve(elem.parentNode); return; } } }); }); observer.observe(document.documentElement, { childList: true, subtree: true }); }); } function inject_controls() { find_controls().then(function(controls) { /* don't inject multiple times */ if (document.querySelector('#speed-control')) return; /* create speed_control element */ var speed_control = document.createElement('select'); speed_control.id = 'speed-control'; speed_control.style.cssText = ` border: none; cursor: pointer; background: none; -moz-appearance: none; -webkit-appearance: none; appearance: none; font-size: 2.2em; text-align: center; `; speed_control.id = 'speed-control'; speed_control.onchange = function() { document.querySelector('.VideoContainer video').playbackRate = this.value; }; speed_control.innerHTML = ` `; /* inject speed_control element */ controls.after(speed_control); /* redo injection, in case of video change, ... */ inject_controls(); }); }; inject_controls();