// ==UserScript== // @name netflix-speed // @version 0.8 // @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) { 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) { /* remove report a problem button */ if (document.querySelector('div.ReportAProblemPopupContainer')) document.querySelector('div.ReportAProblemPopupContainer').remove(); /* don't inject multiple times */ if (document.querySelector('#speed-control')) return; /* create speed_control element */ var speed_control = document.createElement('div'); speed_control.innerHTML = ``; speed_control.id = 'speed-control'; speed_control.style.cssText = ` padding: 0 0 1.68em 0; margin: 0 1.5em;`; speed_control.firstChild.style.cssText = ` -webkit-appearance: none; background: none; border: none; font-size: 2.2em; text-align: right;`; speed_control.firstChild.onchange = function() { document.querySelector('.VideoContainer video').playbackRate = this.value; }; /* inject speed_control element */ controls.before(speed_control); /* redo injection, in case of video change, ... */ inject_controls(); }); }; /* initial run of injection */ inject_controls();