Stop all videos

Stops all videos on the page

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Stop all videos
// @namespace    Stop all videos
// @version      1.2
// @description  Stops all videos on the page
// @author       Nameniok
// @match        *://*/*
// @license      MIT
// @grant        none
// ==/UserScript==

(function() {
const config = {
        blockVideoPreload: true,      // Stop video loading
        blockAutoplay: true,          // Stop automatic playback
        addControls: true,            // Add controls to videos
        initialHidden: false,          // Initially hide videos
        showOnPause: false,            // Show videos on pause
        muteAllVideos: true,          // Mute all videos
        blockedExtensions: ['.mp4', '.webm'],  // Blocked extensions
        useIntersectionObserver: false // Use Intersection Observer for video visibility (autoplaing videos on scroll, false to disable, false is better but may cause problems)
    };

    function stopAndDisablePreload(video) {
        video.pause();
        video.removeAttribute('preload');
      console.log('runned stopAndDisablePreload');
    }

    function stopAndDisablePreloadForAllVideos() {
        Array.from(document.querySelectorAll('video')).forEach(video => {
            stopAndDisablePreload(video);
            removeAutoplayAttribute(video);
            addControlsAttribute(video);
            addCanPlayListener(video);
          console.log('runned stopAndDisablePreloadForAllVideos');

            if (config.initialHidden) {
                video.style.visibility = 'hidden';
            }

            video.addEventListener('loadedmetadata', () => {
                stopAndDisablePreload(video);
                removeAutoplayAttribute(video);
                addControlsAttribute(video);
                addCanPlayListener(video);
              console.log('runned stopAndDisablePreloadForAllVideos loadedmetadata');
            });
        });
    }

    function addCanPlayListener(video) {
        video.addEventListener('canplay', () => {
            stopAndDisablePreload(video);
            removeAutoplayAttribute(video);
            addControlsAttribute(video);
          console.log('runned addCanPlayListener canplay');
            if (config.initialHidden) {
                video.style.visibility = 'visible';
            }
        }, { once: true });

        video.addEventListener('loadedmetadata', () => {
            stopAndDisablePreload(video);
            removeAutoplayAttribute(video);
            addControlsAttribute(video);
          console.log('runned addCanPlayListener loadedmetadata');
            if (config.initialHidden) {
                video.style.visibility = 'visible';
            }
        }, { once: true });

        video.addEventListener('pause', () => {
            if (config.showOnPause) {
                video.style.visibility = 'visible';
            }
        });
    }

    function removeAutoplayAttribute(video) {
        if (config.blockAutoplay) {
            video.removeAttribute('autoplay');
            video.removeEventListener('play', preventAutoplay);
            video.addEventListener('play', preventAutoplay, { once: true });
            console.log('runned removeAutoplayAttribute');
        }
    }

    function addControlsAttribute(video) {
    if (config.addControls) {
        video.setAttribute('controls', 'true');
        console.log('runned addControlsAttribute');

        if (config.muteAllVideos) {
            video.setAttribute('muted', 'true');
        }
    }
}

    function preventAutoplay(event) {
        event.preventDefault();
        event.stopPropagation();
      console.log('runned preventAutoplay event');
    }

    function hasBlockedExtension(source) {
    return source && config.blockedExtensions.some(extension => source.endsWith(extension));
}

    function observeVideos(mutationsList) {
        mutationsList.forEach(mutation => {
            if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
                mutation.addedNodes.forEach(node => {
                    if (node.tagName && node.tagName.toLowerCase() === 'video') {
                        if (config.blockVideoPreload) {
                            stopAndDisablePreload(node);
                          console.log('runned blockVideoPreload mutationobserver');
                        }
                        if (config.blockAutoplay) {
                            removeAutoplayAttribute(node);
                            addControlsAttribute(node);
                            addCanPlayListener(node);
                          console.log('runned blockAutoplay mutationobserver');

                            const videoSource = node.getAttribute('src');
                            if (hasBlockedExtension(videoSource)) {
                                node.pause();
                                stopAndDisablePreload(node);
                                removeAutoplayAttribute(node);
                                console.log('Blocked video with source:', videoSource);
                                return;
                              console.log('runned hasBlockedExtension mutationobserver');
                            }
                        }
                        if (config.initialHidden) {
                            node.style.visibility = 'hidden';
                        }
                        observeVideoVisibility(node);
                    } else if (node.querySelectorAll) {
                        Array.from(node.querySelectorAll('video')).forEach(video => {
                            if (config.blockVideoPreload) {
                                stopAndDisablePreload(video);
                              console.log('runned blockVideoPreload2 mutationobserver');
                            }
                            if (config.blockAutoplay) {
                                removeAutoplayAttribute(video);
                                addControlsAttribute(video);
                                addCanPlayListener(video);
                              console.log('runned blockAutoplay2 mutationobserver');

                                const videoSource = video.getAttribute('src');
                                if (hasBlockedExtension(videoSource)) {
                                    video.pause();
                                    stopAndDisablePreload(video);
                                    removeAutoplayAttribute(video);
                                    configureVideoPreloadAndAutoplay();
                                    console.log('Blocked video with source:', videoSource);
                                    return;
                                  console.log('runned hasBlockedExtension2 mutationobserver');
                                }
                            }
                            if (config.initialHidden) {
                                video.style.visibility = 'hidden';
                            }
                            observeVideoVisibility(video);
                        });
                    }
                });
            }
        });
    }


    function observeVideoVisibility(video) {
    if (!config.useIntersectionObserver) {
        return; // Skip observation if not configured to use Intersection Observer
    }

    const observer = new IntersectionObserver(entries => {
        entries.forEach(entry => {
            if (entry.isIntersecting) {
                video.play().catch(error => { // change "video.play()" to "video.pause()" if you want
                });
            } else {
                // Video is out of view, pause
                video.pause();
            }
        });
    });

    observer.observe(video);
}

    function initObserver() {
    const observer = new MutationObserver(observeVideos);
    const targetNode = document.documentElement;

    const observerConfig = {
        childList: true,
        subtree: true
    };
    observer.observe(targetNode, observerConfig);
}
document.addEventListener("DOMContentLoaded", function() {
        stopAndDisablePreloadForAllVideos();
        initObserver();
    });
        stopAndDisablePreloadForAllVideos();
        initObserver();
}


)();