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

QingJ © 2025

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