Fullscreen Video Speed Controller

Control playback speed, fix A/V sync issues, and seek for fullscreen videos

// ==UserScript==
// @name         Fullscreen Video Speed Controller
// @version      2.0.0
// @description  Control playback speed, fix A/V sync issues, and seek for fullscreen videos
// @author       Wanten
// @copyright    2025 Wanten
// @license      MIT
// @supportURL   https://gist.github.com/WantenMN/c0afabc32a911d4dd10e06cff6bcb211
// @homepageURL  https://gist.github.com/WantenMN/c0afabc32a911d4dd10e06cff6bcb211
// @namespace    https://greasyfork.org/en/scripts/536243
// @run-at       document-end
// @match        https://*/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Helper function to get the fullscreen video element
    function getFullscreenVideo() {
        if (document.fullscreenElement && document.fullscreenElement.tagName === 'VIDEO') {
            return document.fullscreenElement;
        }

        const videos = document.getElementsByTagName('video');
        for (const video of videos) {
            if (video.offsetWidth === window.innerWidth && video.offsetHeight === window.innerHeight) {
                return video;
            }
        }
        return null;
    }

    // Function to set the video speed
    function setVideoSpeed(speed) {
        const video = getFullscreenVideo();
        if (video) {
            video.playbackRate = speed;
        }
    }

    // Function to seek the video forward or backward
    function seekVideo(offset) {
        const video = getFullscreenVideo();
        if (video) {
            video.currentTime += offset;
        }
    }

    // Event listeners for key presses
    document.addEventListener('keydown', function(event) {
        switch(event.key) {
            case 'j':
                setVideoSpeed(1.00);
                break;
            case 'k':
                setVideoSpeed(2);
                break;
            case 'l':
                setVideoSpeed(3.00);
                break;
            case 'i': // Fix audio/video synchronization issues
                seekVideo(0.00001);
                break;
            case 'h':
                seekVideo(-5); // Rewind 5 seconds
                break;
            case ';':
                seekVideo(5); // Fast-forward 5 seconds
                break;
        }
    });
})();