Skip to content

Instantly share code, notes, and snippets.

@SwadicalRag
Last active September 11, 2023 01:28
Show Gist options
  • Save SwadicalRag/1360051370026cbe5aeda0a9cb6c5e0d to your computer and use it in GitHub Desktop.
Save SwadicalRag/1360051370026cbe5aeda0a9cb6c5e0d to your computer and use it in GitHub Desktop.
HTML5 player augment
// ==UserScript==
// @name Augmented HTML5 Video Player
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Adds volume boost to 400% and player speed control to 4x and changes skip forward/backward duration to 2s
// @author swadical
// @match https://*/*
// @include *
// @grant none
// @run-at document-end
// ==/UserScript==
(function() {
"use strict";
/**
* Main function that handles video control augmentations.
*/
function main() {
// Creating a new AudioContext object to work with the Web Audio API
const context = new (window.AudioContext || window.webkitAudioContext)();
const gainNodes = new Map();
// Event listener to listen for keydown events on the window
window.addEventListener("keydown", function(e) {
// Get all video elements on the page
const videoElements = document.querySelectorAll("video");
const activeElement = document.activeElement;
for(let videoElement of videoElements) {
let parentElement = videoElement.closest("div");
// Only proceed if the video is playing or the active element is within the video"s parent element
if(videoElement.paused === false || (parentElement && parentElement.contains(activeElement))) {
// Initialize a new gainNode if it hasn"t been set up for the current video element
if (!gainNodes.has(videoElement)) {
// Creating a new gain node and connecting it to the AudioContext"s destination
const gainNode = context.createGain();
gainNode.connect(context.destination);
// Creating a new media element source and connecting it to the gain node
const source = context.createMediaElementSource(videoElement);
source.connect(gainNode);
// Storing the created nodes in a map
gainNodes.set(videoElement, { source, gainNode });
gainNode.gain.value = 1;
}
// Getting the gain node associated with the current video element
const { gainNode } = gainNodes.get(videoElement);
// Check for arrow key presses to adjust video settings
if(e.code === "ArrowRight" || e.code === "ArrowLeft" || (e.shiftKey && (e.code === "ArrowUp" || e.code === "ArrowDown"))) {
e.preventDefault();
// Check for Shift+Arrow key combinations and adjust video settings accordingly
if(e.shiftKey) {
// Initialize newRate and newVolume variables
let newRate;
let newVolume;
// Logic to adjust playback rate or volume based on the arrow key pressed
if(e.code === "ArrowRight") {
newRate = Math.min(videoElement.playbackRate + 0.25, 4);
} else if(e.code === "ArrowLeft") {
newRate = Math.max(videoElement.playbackRate - 0.25, 0.25);
} else if(e.code === "ArrowUp") {
newVolume = Math.min(gainNode.gain.value + 0.1, 4);
} else {
newVolume = Math.max(gainNode.gain.value - 0.1, 0);
}
// Create or update an overlay to display the new playback rate or volume
let overlay = document.getElementById("playbackRateOverlay");
if(!overlay) {
overlay = document.createElement("div");
overlay.style.position = "absolute";
overlay.style.top = "50%";
overlay.style.left = "50%";
overlay.style.transform = "translate(-50%, -50%)";
overlay.style.backgroundColor = "rgba(0, 0, 0, 0.6)";
overlay.style.padding = "10px";
overlay.style.color = "white";
overlay.style.fontSize = "20px";
overlay.style.fontFamily = "sans-serif";
overlay.style.zIndex = "1000";
overlay.id = "playbackRateOverlay";
videoElement.parentElement.appendChild(overlay);
}
// Update the overlay text based on whether the playback rate or volume was changed
if(typeof newRate !== "undefined") {
videoElement.playbackRate = newRate;
overlay.innerText = `Playback Rate: ${newRate.toFixed(2)}`;
}
else if(typeof newVolume !== "undefined") {
videoElement.volume = 1;
gainNode.gain.value = newVolume;
overlay.innerText = `Playback Volume: ${(newVolume * 100).toFixed(0)}%`;
}
// Display the overlay and remove it after 2 seconds
overlay.style.display = "block";
clearTimeout(window.overlayTimeout);
window.overlayTimeout = setTimeout(() => {
overlay.style.display = "none";
}, 2000);
} else {
// Adjust the video"s current time based on arrow key press without shift key
if(e.code === "ArrowRight") {
videoElement.currentTime += 2;
} else {
videoElement.currentTime -= 2;
}
}
// Stop further propagation of the event
e.stopImmediatePropagation();
break;
}
}
}
}, true);
}
// Injecting the main function script into the document
let script = document.createElement("script");
script.textContent = "(" + main.toString() + ")()";
document.body.appendChild(script);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment