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. });