YouTube 自動跳過廣告

在 YouTube 上自動跳過廣告,提供多種選項

目前為 2024-08-07 提交的版本,檢視 最新版本

// ==UserScript==
// @name            YouTube Ad Skipper
// @name:en         YouTube Ad Skipper
// @name:vi         Tự Động Bỏ Qua Quảng Cáo YouTube
// @name:zh-cn      YouTube 自动跳过广告
// @name:zh-tw      YouTube 自動跳過廣告
// @name:ja         YouTube 広告スキッパー
// @name:ko         YouTube 광고 건너뛰기
// @name:es         YouTube Ad Skipper
// @name:ru         Пропуск рекламы на YouTube
// @name:id         YouTube Ad Skipper
// @name:hi         YouTube विज्ञापन स्किपर
// @namespace    http://tampermonkey.net/
// @version      1.2.1
// @description Automatically skip ads on YouTube with various options
// @description:en Automatically skip ads on YouTube with various options
// @description:vi Tự động bỏ qua quảng cáo trên YouTube với nhiều tùy chọn
// @description:zh-cn 在 YouTube 上自动跳过广告,提供多种选项
// @description:zh-tw 在 YouTube 上自動跳過廣告,提供多種選項
// @description:ja さまざまなオプションで YouTube の広告を自動的にスキップします
// @description:ko 다양한 옵션으로 YouTube 광고를 자동으로 건너뜁니다
// @description:es Salta automáticamente los anuncios en YouTube con varias opciones
// @description:ru Автоматически пропускает рекламу на YouTube с различными настройками
// @description:id Lewati iklan secara otomatis di YouTube dengan berbagai opsi
// @description:hi विभिन्न विकल्पों के साथ YouTube पर विज्ञापनों को स्वचालित रूप से छोड़ें
// @author       Jann
// @icon         https://t2.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=http://youtube.com&size=64
// @license      MIT
// @match        https://*.youtube.com/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_registerMenuCommand
// ==/UserScript==

(function() {
    'use strict';
// Configuration default
    const defaultConfig = {
        skipInterval: 500,
        observerThrottle: 1000,
        muteAds: false,
        hideAdOverlays: true,
        removeAdSlots: true
    };

    let config = GM_getValue('adSkipperConfig', defaultConfig);

    function saveConfig() {
        GM_setValue('adSkipperConfig', config);
    }

    function createSettingsMenu() {
        GM_registerMenuCommand("Configuration Ad Skipper", () => {
            const newConfig = prompt("Import new configuration (JSON):", JSON.stringify(config, null, 2));
            if (newConfig) {
                try {
                    config = JSON.parse(newConfig);
                    saveConfig();
                    alert("Configuration has been updated!");
                } catch (e) {
                    alert("Error: Invalid configuration!");
                }
            }
        });
    }

    function skipAds() {

        const adElement = document.querySelector('.ad-showing');
        if (adElement) {
            const video = document.querySelector('video');
            if (video) {
                video.currentTime = video.duration;
                if (config.muteAds) {
                    video.muted = true;
                }
            }
        }


        const skipButtons = document.querySelectorAll('.ytp-ad-skip-button, .ytp-ad-skip-button-modern');
        skipButtons.forEach(button => button.click());

        if (config.hideAdOverlays) {

            const closeBanner = document.querySelector('.ytp-ad-overlay-close-button');
            if (closeBanner) {
                closeBanner.click();
            }
        }

        if (config.removeAdSlots) {

            const adSlots = document.querySelectorAll('ytd-ad-slot-renderer, ytm-promoted-video-renderer');
            adSlots.forEach(slot => {
                slot.style.display = 'none';
            });
        }
    }


    function debounce(func, wait) {
        let timeout;
        return function executedFunction(...args) {
            const later = () => {
                clearTimeout(timeout);
                func(...args);
            };
            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
        };
    }


    const debouncedSkipAds = debounce(skipAds, config.observerThrottle);
    const observer = new MutationObserver(debouncedSkipAds);


    observer.observe(document.body, {
        childList: true,
        subtree: true
    });


    setInterval(skipAds, config.skipInterval);


    createSettingsMenu();
 })();