Greasy Fork is available in English.

Reddit controls for player

controls for player in new/sh reddit

  1. // ==UserScript==
  2. // @name Reddit controls for player
  3. // @namespace https://greasyfork.org/users/821661
  4. // @match https://www.reddit.com/*
  5. // @match https://new.reddit.com/*
  6. // @match https://sh.reddit.com/*
  7. // @grant none
  8. // @version 1.2
  9. // @author hdyzen
  10. // @description controls for player in new/sh reddit
  11. // @license MIT
  12. // ==/UserScript==
  13. 'use strict';
  14.  
  15. const clickEv = new Event('pointerup', {
  16. bubbles: true,
  17. cancelable: true,
  18. });
  19. let lastVol;
  20. let defaultVol;
  21.  
  22. function observeShplayers() {
  23. const observer = new MutationObserver(mutations => {
  24. const shPlayers = document.querySelectorAll('shreddit-player:not([wControls])');
  25. shPlayers.forEach(shPlayer => {
  26. const video = shPlayer.shadowRoot?.querySelector('video');
  27. const shadow = shPlayer?.shadowRoot;
  28.  
  29. if (video) {
  30. shPlayer.setAttribute('wControls', '');
  31.  
  32. video.addEventListener('keydown', e => keyHandler(e, shadow, video, shPlayer));
  33. }
  34. });
  35. });
  36.  
  37. observer.observe(document.body, {
  38. childList: true,
  39. subtree: true,
  40. });
  41. }
  42. observeShplayers();
  43.  
  44. function toggleFullScreen(element) {
  45. if (!document.fullscreenElement) {
  46. element.requestFullscreen();
  47. } else {
  48. if (document.exitFullscreen) {
  49. document.exitFullscreen();
  50. }
  51. }
  52. }
  53.  
  54. function framePause(video, per = 1) {
  55. if (!video.paused) video.pause();
  56.  
  57. video.currentTime += per / 30;
  58. }
  59.  
  60. function keyHandler(e, shadow, video, shPlayer) {
  61. if (!/ArrowUp|ArrowDown|ArrowLeft|ArrowRight|Space|KeyS|KeyF|KeyM|Comma|Period/.test(e.code)) return;
  62. e.preventDefault();
  63.  
  64. let captions = shadow.querySelector('vds-caption-button');
  65.  
  66. switch (e.code) {
  67. case 'ArrowUp':
  68. if (video.volume + 0.1 <= 1) {
  69. video.volume += 0.1;
  70. } else {
  71. const remainingVolume = 1 - video.volume;
  72. video.volume += remainingVolume;
  73. }
  74. lastVol = video.volume;
  75. break;
  76. case 'ArrowDown':
  77. if (video.volume - 0.1 >= 0) {
  78. video.volume -= 0.1;
  79. } else {
  80. const remainingVolume = 0 + video.volume;
  81. video.volume -= remainingVolume;
  82. }
  83. lastVol = video.volume === 0 ? 0.1 : video.volume;
  84. break;
  85. case 'ArrowLeft':
  86. if (e.ctrlKey) {
  87. video.currentTime -= 30;
  88. } else if (e.shiftKey) {
  89. video.currentTime -= 10;
  90. } else {
  91. video.currentTime -= 5;
  92. }
  93. break;
  94. case 'ArrowRight':
  95. if (e.ctrlKey) {
  96. video.currentTime += 30;
  97. } else if (e.shiftKey) {
  98. video.currentTime += 10;
  99. } else {
  100. video.currentTime += 5;
  101. }
  102. break;
  103. case 'Space':
  104. if (video.paused) {
  105. video.play();
  106. } else {
  107. video.pause();
  108. }
  109. break;
  110. case 'KeyS':
  111. captions?.dispatchEvent(clickEv);
  112. break;
  113. case 'KeyF':
  114. toggleFullScreen(shPlayer);
  115. break;
  116. case 'KeyM':
  117. if (video.volume) {
  118. video.volume = 0;
  119. } else {
  120. video.volume = lastVol;
  121. }
  122. break;
  123. case 'Period':
  124. framePause(video, 1);
  125. break;
  126. case 'Comma':
  127. framePause(video, -1);
  128. break;
  129. default:
  130. break;
  131. }
  132. }
  133.  
  134. document.documentElement.addEventListener('click', e => {
  135. if (e.target.matches('shreddit-player')) {
  136. e.target.shadowRoot.querySelector('video').focus();
  137. }
  138. });