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

  1. // ==UserScript==
  2. // @name Showtime: enable YouTube-style keyboard controls
  3. // @namespace showtime.keyboard
  4. // @version 0.4
  5. // @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%)
  6. // @match https://showtime.com/*
  7. // @match https://www.showtime.com/*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13.  
  14. // change these constants if you prefer to use a different key
  15. // (or change the letter to uppercase if you want the shortcut to require the use of Shift)
  16. const FULL_SCREEN_KEY = 'f';
  17. const PLAY_PAUSE_KEY = 'k';
  18. const FORWARDS_TEN_SECONDS_KEY = 'l';
  19. const BACKWARDS_TEN_SECONDS_KEY = 'j';
  20. const FORWARDS_FIVE_SECONDS_KEY = 'ArrowRight';
  21. const BACKWARDS_FIVE_SECONDS_KEY = 'ArrowLeft';
  22. const CLOSED_CAPTIONS_KEY = 'c';
  23. const MUTE_UNMUTE_KEY = 'm';
  24. const PICTURE_IN_PICTURE_KEY = 'p';
  25. const NUMBER_KEYS_ENABLED = true; // 0 for 0%, 1 for 10%… up to 9 for 90%
  26. const CODE_ZERO = 48; // keycode for character '0'
  27.  
  28. function clickButton(className) {
  29. const buttons = document.querySelectorAll('button.' + className);
  30. if (buttons && buttons.length == 1) {
  31. buttons[0].click();
  32. } else {
  33. console.error('Button not found!');
  34. }
  35. }
  36.  
  37. function isPlaying(videoElement) {
  38. return !!(videoElement.currentTime > 0 && !videoElement.paused && !videoElement.ended && videoElement.readyState > 2);
  39. }
  40.  
  41. addEventListener("keydown", function(e) {
  42. if (e.ctrlKey || e.altKey) { // return early if any modifier key like Control or Alt is part of the key press
  43. return;
  44. }
  45. const videos = document.getElementsByTagName('video');
  46. const video = videos && videos.length == 1 ? videos[0] : null;
  47.  
  48. if (e.key == FULL_SCREEN_KEY) {
  49. clickButton(window.innerHeight == screen.height ? 'exit-fullscreen' : 'enter-fullscreen');
  50. } else if (e.key == PLAY_PAUSE_KEY) {
  51. clickButton(video && isPlaying(video) ? 'pause' : 'play');
  52. } else if (e.key == MUTE_UNMUTE_KEY) {
  53. clickButton('volume');
  54. } else if (e.key == PICTURE_IN_PICTURE_KEY) {
  55. if (document.pictureInPictureElement) {
  56. document.exitPictureInPicture();
  57. } else {
  58. video && video.requestPictureInPicture();
  59. }
  60. } else if (e.key == FORWARDS_TEN_SECONDS_KEY && video) {
  61. video.currentTime += 10;
  62. } else if (e.key == BACKWARDS_TEN_SECONDS_KEY && video) {
  63. video.currentTime -= 10;
  64. } else if (e.key == FORWARDS_FIVE_SECONDS_KEY && video) {
  65. video.currentTime += 5;
  66. } else if (e.key == BACKWARDS_FIVE_SECONDS_KEY && video) {
  67. video.currentTime -= 5;
  68. } else if (NUMBER_KEYS_ENABLED && e.keyCode >= CODE_ZERO && e.keyCode <= CODE_ZERO + 9) {
  69. video.currentTime = (e.keyCode - CODE_ZERO) * (video.duration / 10.0);
  70. } else if (e.key == CLOSED_CAPTIONS_KEY) {
  71. const ccContainer = document.querySelectorAll('div.player-closed-captioning-container > div');
  72. if (ccContainer && ccContainer.length == 1) {
  73. clickButton(ccContainer[0].classList.contains('closed-captioning-enabled') ? 'closed-captioning-disable' : 'closed-captioning-enable');
  74. } else {
  75. console.error('No CC container found');
  76. }
  77. }
  78. });
  79. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址