Showtime: enable YouTube-style keyboard controls

Use similar controls as on YouTube when watching Showtime (`f` for full screen, `k` to play/pause, `c` for captions, `m` to mute/unmute, `p` to enable/disable PiP, `j`/`l` to go back/skip 10 seconds, left/right arrows for 5 seconds, `0`..`9` for 0% .. 90%)

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==UserScript==
// @name         Showtime: enable YouTube-style keyboard controls
// @namespace    showtime.keyboard
// @version      0.4
// @description  Use similar controls as on YouTube when watching Showtime (`f` for full screen, `k` to play/pause, `c` for captions, `m` to mute/unmute, `p` to enable/disable PiP, `j`/`l` to go back/skip 10 seconds, left/right arrows for 5 seconds, `0`..`9` for 0% .. 90%)
// @match        https://showtime.com/*
// @match        https://www.showtime.com/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // change these constants if you prefer to use a different key
    // (or change the letter to uppercase if you want the shortcut to require the use of Shift)
    const FULL_SCREEN_KEY = 'f';
    const PLAY_PAUSE_KEY = 'k';
    const FORWARDS_TEN_SECONDS_KEY = 'l';
    const BACKWARDS_TEN_SECONDS_KEY = 'j';
    const FORWARDS_FIVE_SECONDS_KEY = 'ArrowRight';
    const BACKWARDS_FIVE_SECONDS_KEY = 'ArrowLeft';
    const CLOSED_CAPTIONS_KEY = 'c';
    const MUTE_UNMUTE_KEY = 'm';
    const PICTURE_IN_PICTURE_KEY = 'p';
    const NUMBER_KEYS_ENABLED = true; // 0 for 0%, 1 for 10%… up to 9 for 90%
    const CODE_ZERO = 48; // keycode for character '0'

    function clickButton(className) {
        const buttons = document.querySelectorAll('button.' + className);
        if (buttons && buttons.length == 1) {
            buttons[0].click();
        } else {
            console.error('Button not found!');
        }
    }

    function isPlaying(videoElement) {
        return !!(videoElement.currentTime > 0 && !videoElement.paused && !videoElement.ended && videoElement.readyState > 2);
    }

    addEventListener("keydown", function(e) {
        if (e.ctrlKey || e.altKey) { // return early if any modifier key like Control or Alt is part of the key press
            return;
        }
        const videos = document.getElementsByTagName('video');
        const video = videos && videos.length == 1 ? videos[0] : null;

        if (e.key == FULL_SCREEN_KEY) {
            clickButton(window.innerHeight == screen.height ? 'exit-fullscreen' : 'enter-fullscreen');
        } else if (e.key == PLAY_PAUSE_KEY) {
            clickButton(video && isPlaying(video) ? 'pause' : 'play');
        } else if (e.key == MUTE_UNMUTE_KEY) {
            clickButton('volume');
        } else if (e.key == PICTURE_IN_PICTURE_KEY) {
            if (document.pictureInPictureElement) {
                document.exitPictureInPicture();
            } else {
                video && video.requestPictureInPicture();
            }
        } else if (e.key == FORWARDS_TEN_SECONDS_KEY && video) {
            video.currentTime += 10;
        } else if (e.key == BACKWARDS_TEN_SECONDS_KEY && video) {
            video.currentTime -= 10;
        } else if (e.key == FORWARDS_FIVE_SECONDS_KEY && video) {
            video.currentTime += 5;
        } else if (e.key == BACKWARDS_FIVE_SECONDS_KEY && video) {
            video.currentTime -= 5;
        } else if (NUMBER_KEYS_ENABLED && e.keyCode >= CODE_ZERO && e.keyCode <= CODE_ZERO + 9) {
            video.currentTime = (e.keyCode - CODE_ZERO) * (video.duration / 10.0);
        } else if (e.key == CLOSED_CAPTIONS_KEY) {
            const ccContainer = document.querySelectorAll('div.player-closed-captioning-container > div');
            if (ccContainer && ccContainer.length == 1) {
                clickButton(ccContainer[0].classList.contains('closed-captioning-enabled') ? 'closed-captioning-disable' : 'closed-captioning-enable');
            } else {
                console.error('No CC container found');
            }
        }
    });
})();