🏠 Home 

Stop all videos

Stops all videos on the page


安装此脚本?
  1. // ==UserScript==
  2. // @name Stop all videos
  3. // @namespace Stop all videos
  4. // @version 1.2
  5. // @description Stops all videos on the page
  6. // @author Nameniok
  7. // @match *://*/*
  8. // @license MIT
  9. // @grant none
  10. // ==/UserScript==
  11. (function() {
  12. const config = {
  13. blockVideoPreload: true, // Stop video loading
  14. blockAutoplay: true, // Stop automatic playback
  15. addControls: true, // Add controls to videos
  16. initialHidden: false, // Initially hide videos
  17. showOnPause: false, // Show videos on pause
  18. muteAllVideos: true, // Mute all videos
  19. blockedExtensions: ['.mp4', '.webm'], // Blocked extensions
  20. useIntersectionObserver: false // Use Intersection Observer for video visibility (autoplaing videos on scroll, false to disable, false is better but may cause problems)
  21. };
  22. function stopAndDisablePreload(video) {
  23. video.pause();
  24. video.removeAttribute('preload');
  25. console.log('runned stopAndDisablePreload');
  26. }
  27. function stopAndDisablePreloadForAllVideos() {
  28. Array.from(document.querySelectorAll('video')).forEach(video => {
  29. stopAndDisablePreload(video);
  30. removeAutoplayAttribute(video);
  31. addControlsAttribute(video);
  32. addCanPlayListener(video);
  33. console.log('runned stopAndDisablePreloadForAllVideos');
  34. if (config.initialHidden) {
  35. video.style.visibility = 'hidden';
  36. }
  37. video.addEventListener('loadedmetadata', () => {
  38. stopAndDisablePreload(video);
  39. removeAutoplayAttribute(video);
  40. addControlsAttribute(video);
  41. addCanPlayListener(video);
  42. console.log('runned stopAndDisablePreloadForAllVideos loadedmetadata');
  43. });
  44. });
  45. }
  46. function addCanPlayListener(video) {
  47. video.addEventListener('canplay', () => {
  48. stopAndDisablePreload(video);
  49. removeAutoplayAttribute(video);
  50. addControlsAttribute(video);
  51. console.log('runned addCanPlayListener canplay');
  52. if (config.initialHidden) {
  53. video.style.visibility = 'visible';
  54. }
  55. }, { once: true });
  56. video.addEventListener('loadedmetadata', () => {
  57. stopAndDisablePreload(video);
  58. removeAutoplayAttribute(video);
  59. addControlsAttribute(video);
  60. console.log('runned addCanPlayListener loadedmetadata');
  61. if (config.initialHidden) {
  62. video.style.visibility = 'visible';
  63. }
  64. }, { once: true });
  65. video.addEventListener('pause', () => {
  66. if (config.showOnPause) {
  67. video.style.visibility = 'visible';
  68. }
  69. });
  70. }
  71. function removeAutoplayAttribute(video) {
  72. if (config.blockAutoplay) {
  73. video.removeAttribute('autoplay');
  74. video.removeEventListener('play', preventAutoplay);
  75. video.addEventListener('play', preventAutoplay, { once: true });
  76. console.log('runned removeAutoplayAttribute');
  77. }
  78. }
  79. function addControlsAttribute(video) {
  80. if (config.addControls) {
  81. video.setAttribute('controls', 'true');
  82. console.log('runned addControlsAttribute');
  83. if (config.muteAllVideos) {
  84. video.setAttribute('muted', 'true');
  85. }
  86. }
  87. }
  88. function preventAutoplay(event) {
  89. event.preventDefault();
  90. event.stopPropagation();
  91. console.log('runned preventAutoplay event');
  92. }
  93. function hasBlockedExtension(source) {
  94. return source && config.blockedExtensions.some(extension => source.endsWith(extension));
  95. }
  96. function observeVideos(mutationsList) {
  97. mutationsList.forEach(mutation => {
  98. if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
  99. mutation.addedNodes.forEach(node => {
  100. if (node.tagName && node.tagName.toLowerCase() === 'video') {
  101. if (config.blockVideoPreload) {
  102. stopAndDisablePreload(node);
  103. console.log('runned blockVideoPreload mutationobserver');
  104. }
  105. if (config.blockAutoplay) {
  106. removeAutoplayAttribute(node);
  107. addControlsAttribute(node);
  108. addCanPlayListener(node);
  109. console.log('runned blockAutoplay mutationobserver');
  110. const videoSource = node.getAttribute('src');
  111. if (hasBlockedExtension(videoSource)) {
  112. node.pause();
  113. stopAndDisablePreload(node);
  114. removeAutoplayAttribute(node);
  115. console.log('Blocked video with source:', videoSource);
  116. return;
  117. console.log('runned hasBlockedExtension mutationobserver');
  118. }
  119. }
  120. if (config.initialHidden) {
  121. node.style.visibility = 'hidden';
  122. }
  123. observeVideoVisibility(node);
  124. } else if (node.querySelectorAll) {
  125. Array.from(node.querySelectorAll('video')).forEach(video => {
  126. if (config.blockVideoPreload) {
  127. stopAndDisablePreload(video);
  128. console.log('runned blockVideoPreload2 mutationobserver');
  129. }
  130. if (config.blockAutoplay) {
  131. removeAutoplayAttribute(video);
  132. addControlsAttribute(video);
  133. addCanPlayListener(video);
  134. console.log('runned blockAutoplay2 mutationobserver');
  135. const videoSource = video.getAttribute('src');
  136. if (hasBlockedExtension(videoSource)) {
  137. video.pause();
  138. stopAndDisablePreload(video);
  139. removeAutoplayAttribute(video);
  140. configureVideoPreloadAndAutoplay();
  141. console.log('Blocked video with source:', videoSource);
  142. return;
  143. console.log('runned hasBlockedExtension2 mutationobserver');
  144. }
  145. }
  146. if (config.initialHidden) {
  147. video.style.visibility = 'hidden';
  148. }
  149. observeVideoVisibility(video);
  150. });
  151. }
  152. });
  153. }
  154. });
  155. }
  156. function observeVideoVisibility(video) {
  157. if (!config.useIntersectionObserver) {
  158. return; // Skip observation if not configured to use Intersection Observer
  159. }
  160. const observer = new IntersectionObserver(entries => {
  161. entries.forEach(entry => {
  162. if (entry.isIntersecting) {
  163. video.play().catch(error => { // change "video.play()" to "video.pause()" if you want
  164. });
  165. } else {
  166. // Video is out of view, pause
  167. video.pause();
  168. }
  169. });
  170. });
  171. observer.observe(video);
  172. }
  173. function initObserver() {
  174. const observer = new MutationObserver(observeVideos);
  175. const targetNode = document.documentElement;
  176. const observerConfig = {
  177. childList: true,
  178. subtree: true
  179. };
  180. observer.observe(targetNode, observerConfig);
  181. }
  182. document.addEventListener("DOMContentLoaded", function() {
  183. stopAndDisablePreloadForAllVideos();
  184. initObserver();
  185. });
  186. stopAndDisablePreloadForAllVideos();
  187. initObserver();
  188. }
  189. )();