咪咕动态弹幕关键词屏蔽工具

从页面动态获取关键词并屏蔽相关弹幕(适配特殊弹幕结构)

安裝腳本?
作者推薦腳本

您可能也會喜歡 咪咕视频增强

安裝腳本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         咪咕动态弹幕关键词屏蔽工具
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  从页面动态获取关键词并屏蔽相关弹幕(适配特殊弹幕结构)
// @author       klingeling
// @match        https://www.miguvideo.com/p/live/*
// @match        https://www.miguvideo.com/p/pugcLive/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // 存储当前屏蔽词列表
    let bannedWords = [];
    let bannedRegex = null;
    let observerActive = false;

    // 从页面获取屏蔽词
    function updateBannedWords() {
        const hotWordsList = document.querySelector('.www-hotWords-list');
        if (hotWordsList) {
            const items = hotWordsList.querySelectorAll('.www-hotWords-item');
            bannedWords = Array.from(items).map(item => item.textContent.trim());

            // 创建正则表达式时对特殊字符进行转义
            if (bannedWords.length > 0) {
                const escapedWords = bannedWords.map(word =>
                    word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
                );
                bannedRegex = new RegExp(escapedWords.join("|"), "i");
                console.log('【klingleing】屏蔽词已更新:', bannedWords);
            } else {
                bannedRegex = null;
            }
        }
    }

    // 检查并隐藏匹配的弹幕
    function hideMatchingDanmu(node) {
        if (!bannedRegex || !node || !node.style) return;

        const danmuText = node.textContent || node.innerText;
        if (danmuText && bannedRegex.test(danmuText)) {
            node.style.display = 'none';
            node.style.visibility = 'hidden';
            // console.log('【klingleing】已屏蔽弹幕:', danmuText);
        }
    }

    // 检查已有的弹幕
    function checkExistingDanmu() {
        if (!bannedRegex) return;

        // 适配特殊弹幕容器结构
        const danmuContainer = document.querySelector('[class*="danmu-wrapper"], [class*="danmu"]');
        if (!danmuContainer) return;

        danmuContainer.querySelectorAll('div[data-line-index]').forEach(danmu => {
            hideMatchingDanmu(danmu);
        });
    }

    // 创建观察器来检测DOM变化
    const createObserver = () => {
        if (observerActive) return;

        // 查找弹幕容器(适配特殊类名)
        const danmuContainer = document.querySelector('[class*="danmu-wrapper"], [class*="danmu"]');
        if (!danmuContainer) {
            console.log('【klingleing】未找到弹幕容器');
            return;
        }

        // 观察弹幕容器的变化
        const danmuObserver = new MutationObserver(function(mutations) {
            mutations.forEach(function(mutation) {
                mutation.addedNodes.forEach(function(node) {
                    if (node.nodeType === Node.ELEMENT_NODE) {
                        // 检查是否是弹幕元素
                        const danmu = node.matches('div[data-line-index]') ? node :
                                      node.querySelector && node.querySelector('div[data-line-index]');
                        if (danmu) {
                            hideMatchingDanmu(danmu);
                        }
                    }
                });
            });
        });

        // 观察热门关键词的变化
        const hotWordsObserver = new MutationObserver(function() {
            updateBannedWords();
            checkExistingDanmu();
        });

        // 启动观察器
        danmuObserver.observe(danmuContainer, {
            childList: true,
            subtree: true
        });

        const hotWordsContainer = document.querySelector('.www-hotWords-list');
        if (hotWordsContainer) {
            hotWordsObserver.observe(hotWordsContainer, {
                childList: true,
                subtree: true,
                characterData: true
            });
        }

        observerActive = true;
        console.log('【klingleing】弹幕观察器已启动');
    };

    // 初始化
    function init() {
        updateBannedWords();

        // 加强型元素检测
        const checkElements = setInterval(() => {
            const danmuExists = document.querySelector('[class*="danmu"]');
            const hotWordsExists = document.querySelector('.www-hotWords-list');

            if (danmuExists && hotWordsExists) {
                clearInterval(checkElements);
                createObserver();
                checkExistingDanmu();

                // 额外检查,确保弹幕容器找到
                if (!observerActive) {
                    console.log('【klingleing】重新尝试创建观察器...');
                    setTimeout(createObserver, 500);
                }
            }
        }, 500);
    }

    // 启动脚本
    if (document.readyState === 'complete') {
        setTimeout(init, 1000);
    } else {
        window.addEventListener('load', function() {
            setTimeout(init, 1000);
        }, {once: true});
    }

    // 更频繁的定期检查
    const checkInterval = setInterval(() => {
        if (!observerActive) {
            createObserver();
        }
        checkExistingDanmu();
    }, 2000);

    // 清理间隔的函数(虽然油猴脚本通常不需要)
    window.addEventListener('beforeunload', () => {
        clearInterval(checkInterval);
    });
})();