Greasy Fork

Greasy Fork is available in English.

小红书视频取消静音

小红书网页端:视频自动取消静音。

// ==UserScript==
// @name         小红书视频取消静音
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  小红书网页端:视频自动取消静音。
// @match        *://www.xiaohongshu.com/*
// @icon         https://www.xiaohongshu.com/favicon.ico
// @run-at       document-start
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    // ========== 自动取消视频静音 ==========
    function handleVideo(video) {
        if (video.__xhsAutoUnmute) return;
        video.__xhsAutoUnmute = true;

        // 播放时自动解除静音
        video.addEventListener('play', function() {
            if (video.muted) video.muted = false;
            if (video.volume === 0) video.volume = 1;
        });

        // 首次处理
        if (video.muted) video.muted = false;
        if (video.volume === 0) video.volume = 1;
    }

    function scanAndHandleVideos() {
        document.querySelectorAll('video').forEach(handleVideo);
    }

    function setupVideoObserver() {
        if (window.__xhsVideoUnmuteObserver) return;
        window.__xhsVideoUnmuteObserver = true;

        scanAndHandleVideos();
        const observer = new MutationObserver(mutations => {
            mutations.forEach(mutation => {
                mutation.addedNodes.forEach(node => {
                    if (node.nodeName === 'VIDEO') {
                        handleVideo(node);
                    } else if (node.querySelectorAll) {
                        node.querySelectorAll('video').forEach(handleVideo);
                    }
                });
            });
        });
        observer.observe(document.body, { childList: true, subtree: true });
    }

    function waitForHeadAndBody(fn) {
        if (document.head && document.body) {
            fn();
        } else {
            const observer = new MutationObserver(() => {
                if (document.head && document.body) {
                    observer.disconnect();
                    fn();
                }
            });
            observer.observe(document.documentElement, { childList: true, subtree: true });
        }
    }
    waitForHeadAndBody(setupVideoObserver);

    // 保底,页面完全加载时再执行一遍(抗SPA/异步加载)
    window.addEventListener('DOMContentLoaded', () => {
        scanAndHandleVideos();
    });
})();