Greasy Fork

Greasy Fork is available in English.

Douyin live stream optimization(优化网页)

优化直播间体验:删除指定div,屏蔽礼物特效(兼容三种结构),切换最高画质

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

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

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Douyin live stream optimization(优化网页)
// @namespace    http://tampermonkey.net/
// @version      2.0
// @description  优化直播间体验:删除指定div,屏蔽礼物特效(兼容三种结构),切换最高画质
// @match        https://*.douyin.com/*
// @run-at       document-idle
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // 模拟点击函数,兼容 React/Vue
    function simulateClick(el) {
        if(!el) return;
        el.scrollIntoView({behavior: 'smooth', block: 'center'});
        ['mousedown', 'mouseup', 'click'].forEach(type => {
            const event = new MouseEvent(type, {view: window, bubbles: true, cancelable: true, composed: true});
            el.dispatchEvent(event);
        });
        console.log('模拟点击元素:', el);
    }

    // 删除指定元素并按B键(延迟5秒)
    function removeElementsAndPressB() {
        let removed = false;

        // 删除 class 元素
        document.querySelectorAll('div.aqK_4_5U.R7IW3rpb').forEach(el => {
            console.log('删除 class 元素:', el);
            el.remove();
            removed = true;
        });

        // 删除 BottomLayout
        const bottomLayout = document.getElementById('BottomLayout');
        if(bottomLayout){
            console.log('删除 BottomLayout 元素:', bottomLayout);
            bottomLayout.remove();
            removed = true;
        }

        // 删除额外 class 元素
        const extraEl = document.querySelector('div._D4WLewc.GDP2iTsQ');
        if(extraEl){
            console.log('删除额外元素:', extraEl);
            extraEl.remove();
            removed = true;
        }

        // 删除后延迟5秒按B键
        if(removed){
            setTimeout(() => {
                console.log('触发键盘B');
                const event = new KeyboardEvent('keydown', {key: 'b', code: 'KeyB', keyCode: 66, which: 66, bubbles: true, cancelable: true});
                document.dispatchEvent(event);
            }, 5000);
        }
    }

    // 循环检测并屏蔽礼物特效(兼容三种结构)
    function monitorGiftEffect() {
        setInterval(() => {
            const elements = Array.from(document.querySelectorAll(
                'div.WoNKVQmY.Z20k_Nsy, div.OwaHUR7p.M3rvLCL0, div.PyUjXuWV.hRnC6O2k'
            )).filter(div => div.textContent.includes('礼物特效'));

            elements.forEach(el => {
                const stateText = el.textContent.trim();
                console.log('当前礼物特效状态:', stateText);

                const switchBtn = el.parentElement?.querySelector('div[data-e2e="effect-switch"]');
                if(switchBtn && stateText === '屏蔽礼物特效'){
                    simulateClick(switchBtn);
                    console.log('自动点击屏蔽礼物特效');
                }
            });
        }, 1000);
    }

    // 循环切换到最高画质
    function switchToHighestQualityLoop() {
        const currentEl = document.querySelector('div[data-e2e="quality"]');
        const selector = document.querySelector('div[data-e2e="quality-selector"]');
        if(!currentEl || !selector) {
            setTimeout(switchToHighestQualityLoop, 500);
            return;
        }

        const currentQuality = currentEl.textContent.trim();
        const priority = ['原画','超清','高清','标清','自动(标清)'];
        const highest = priority[0];

        if(currentQuality === highest){
            console.log('已切换到最高画质:', currentQuality);
            return;
        }

        const options = Array.from(selector.querySelectorAll('div.D7UhJyco'));
        const target = options.find(el => el.textContent.trim() === highest);
        if(target){
            const clickable = target.closest('div.PAeJVT8Y');
            if(clickable){
                simulateClick(clickable);
                console.log('正在切换到最高画质:', highest);
            }
        }

        setTimeout(switchToHighestQualityLoop, 500);
    }

    // 主函数,每 3 秒轮询
    function main() {
        // 检测是否在直播间
        const liveFlag = document.querySelector('div.CkKPEcld, div.ej6cQnWN');
        if(!liveFlag){
            //console.log('未检测到直播间标志元素,脚本跳过执行');
            return; // 不在直播间,跳过
        }

        removeElementsAndPressB();
        monitorGiftEffect();
        switchToHighestQualityLoop();
    }

    // SPA URL 支持
    let lastUrl = location.href;
    setInterval(() => {
        if(location.href !== lastUrl){
            console.log('检测到 URL 改变:', location.href);
            lastUrl = location.href;
            main();
        }
    }, 500);

    // 每 3 秒轮询 main
    setInterval(main, 3000);

    // MutationObserver 监听动态生成元素
    const observer = new MutationObserver(() => {
        removeElementsAndPressB();
    });
    observer.observe(document.body, {childList: true, subtree: true});

})();