🏠 Home 

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%)

// ==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');
}
}
});
})();