// ==UserScript== // @name Video Element Rate Controller Re-dux // @namespace https://github.com/mirnhoj/video-element-playbackrate-setter // @version 1.0 // @description Add keyboard shortcuts that will increase/decrease the playback rate for video elements. // @include http*://*.youtube.com/* // @include http*://*.gfycat.com/* // @include http*://*.vimeo.com/* // @include https://www.facebook.com/video.php* // @include https://www.facebook.com/*/videos/* // @include https://www.kickstarter.com/* // @require https://cdnjs.cloudflare.com/ajax/libs/big.js/5.1.2/big.js // @grant none // @downloadURL none // ==/UserScript== /* jshint esversion: 6 */ // // if you want to extend the functionality of this script to other sites // besides youtube, add additional @include keys to the metadata block. // // if you want to change the default playback rate from 1x, change the line // "var currentPlaybackRate = 1;" to equal something other than 1, like 1.3 to // have all videos start playing at an increased speed, or 0.7 to have all // videos start playing at a decreased speed. // // if you want change the granularity of the playback rate adjustment, change // the line "var speedStep = 0.1;" to equal something other than 0.1, like 0.01 // for more granular adjustments, or 0.25 for less granular adjustments. var currentPlaybackRate = 1; // default playback rate. var speedStep = 0.125; // how much to modify speed for each keypress var displayTimeMilliSec = 1500; // how long to show the current speed indicator in milliseconds var enhancerExtention = true; // set to false if you aren't using Enhancer for Youtube var infobox = document.createElement("h1"); infobox.setAttribute("id", "playbackrate-indicator"); infobox.style.position = "absolute"; infobox.style.top = "10%"; infobox.style.right = "10%"; infobox.style.color = "rgba(255, 0, 0, 1)"; infobox.style.zIndex = "99999"; // ensures that it shows above other elements. infobox.style.visibility = "hidden"; infobox.style.marginTop = "3%"; var timeoutID; var showDisplay = false; var pref = "preference-changed"; var eventName = "speed"; if (document.readyState !== "loading") { onReady(); // Or setTimeout(onReady, 0); if you want it consistently async } else { document.addEventListener("DOMContentLoaded", onReady); } function setPlaybackRate(rate, showInfobox) { rate = new Big(rate); // grab the video elements and set their playback rate. var videoElement = document.getElementsByTagName("video")[0]; videoElement.playbackRate = rate; infobox.innerHTML = rate + "x"; // add infobox to dom if it doesn't already exist. if (videoElement && !document.getElementById("playbackrate-indicator")) { videoElement.parentElement.appendChild(infobox); } // show infobox and update rate indicator. if (showInfobox) { infobox.style.visibility = "visible"; // clear out any previous timers and have the infobox hide after the pre-set time period window.clearTimeout(timeoutID); timeoutID = window.setTimeout(function() { infobox.style.visibility = "hidden"; }, displayTimeMilliSec); showDisplay = false; } } // mimic vlc keyboard shortcuts function addKeyListener() { window.addEventListener('keydown', function(event) { var key = event.key; var videoElement = document.getElementsByTagName("video")[0]; currentPlaybackRate = videoElement.playbackRate; switch (key) { // decrease playback rate if '[' is pressed case "[": currentPlaybackRate -= speedStep; showDisplay = true; setPlaybackRate(currentPlaybackRate, showDisplay); break; // increase playback rate if ']' is pressed case "]": currentPlaybackRate += speedStep; showDisplay = true; setPlaybackRate(currentPlaybackRate, showDisplay); break; } if (enhancerExtention === true) { window.postMessage({ enhancerforyoutube: pref, name: eventName, value: currentPlaybackRate }, "*"); } }); } // show the current speed display on the video when mouse wheel is rolled on the speed element if using Enhancer For Youtube function addWheelListener() { var enhancerToolbar = document.getElementById("enhancer-for-youtube-toolbar"); var enhancerToolbarChildren = enhancerToolbar.children[0].children; for (var i = 0; i < enhancerToolbarChildren.length ; i++ ) { if (enhancerToolbarChildren[i].dataset.name === eventName) { var speedChild = enhancerToolbarChildren[i]; }} if (speedChild) { speedChild.addEventListener('wheel', function(event) { var wDelta = event.wheelDelta < 0 ? 'down' : 'up'; var videoElement = document.getElementsByTagName("video")[0]; currentPlaybackRate = videoElement.playbackRate; switch (wDelta) { case "down": // currentPlaybackRate -= speedStep; // uncomment to actually modify the playback speed showDisplay = true; setPlaybackRate(currentPlaybackRate, showDisplay); break; case "up": // currentPlaybackRate += speedStep; // uncomment to actually modify the playback speed showDisplay = true; setPlaybackRate(currentPlaybackRate, showDisplay); break; } }); } } async function onReady() { addKeyListener(); if (enhancerExtention === true) { var i = 0; do { await wait(200); i++ } while (!document.getElementById("enhancer-for-youtube-toolbar") && i < 50); onExtentionReady(); // Or setTimeout(onReady, 0); if you want it consistently async } } function wait(time) { return new Promise(resolve => { setTimeout(() => { resolve(); }, time); }); } function onExtentionReady() { addWheelListener(); }