Bye Bye YouTube Ads

Automatically block/skip YouTube video ads on www.youtube.com (desktop only)

目前為 2025-05-07 提交的版本,檢視 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name        Bye Bye YouTube Ads
// @version     1.0
// @description Automatically block/skip YouTube video ads on www.youtube.com (desktop only)
// @author      DishantX
// @match       *://www.youtube.com/*
// @exclude     *://www.youtube.com/*/music*
// @exclude     *://music.youtube.com/*
// @exclude     *://m.youtube.com/*
// @grant       none
// @namespace https://greasyfork.org/users/1467023
// ==/UserScript==

(function() {
    'use strict';

    // Click the YouTube "Skip Ad" button if present.
    function clickSkipButton() {
        const skipBtn = document.querySelector('button.ytp-ad-skip-button, button.ytp-ad-skip-button-modern');
        if (skipBtn) {
            skipBtn.click();
            return true;
        }
        return false;
    }

    // Skip an unskippable ad by jumping to the video's end.
    function skipUnskippableAd() {
        const video = document.querySelector('video');
        if (video && video.duration && isFinite(video.duration)) {
            video.currentTime = video.duration;
        }
    }

    // Dismiss YouTube's adblock/premium popups if they appear.
    function handleAdBlockPopup() {
        // "No thanks" button on the upsell dialog.
        const noThanks = document.querySelector('yt-upsell-dialog-renderer tp-yt-paper-button[aria-label="No thanks"]');
        if (noThanks) {
            noThanks.click();
            return;
        }
        // "I understand and wish to proceed" button on another dialog.
        const proceed = document.querySelector('yt-button-renderer tp-yt-paper-button[aria-label="I understand and wish to proceed"]');
        if (proceed) {
            proceed.click();
            return;
        }
        // If a popup container is open with no close button, hide it.
        const popup = document.querySelector('ytd-popup-container');
        if (popup && popup.style.display !== 'none') {
            popup.style.display = 'none';
        }
    }

    // Set up a MutationObserver to watch for ad-related DOM changes.
    const observer = new MutationObserver((mutationsList, obs) => {
        // If an ad is playing (player has 'ad-showing' class) then try to skip it.
        const player = document.getElementById('movie_player');
        if (player && player.classList.contains('ad-showing')) {
            // First try clicking the skip button if it exists.
            if (!clickSkipButton()) {
                // If no skip button, jump the ad to the end.
                skipUnskippableAd();
            }
        }
        // Also attempt to dismiss any adblock warning popups.
        handleAdBlockPopup();
    });

    // Observe the entire document for added/removed nodes (needed because YouTube is an SPA).
    observer.observe(document, { childList: true, subtree: true });

    // Run skip logic once immediately after page load in case an ad is already showing.
    if (document.readyState === 'complete' || document.readyState === 'interactive') {
        const player = document.getElementById('movie_player');
        if (player && player.classList.contains('ad-showing')) {
            if (!clickSkipButton()) {
                skipUnskippableAd();
            }
        }
        handleAdBlockPopup();
    }
})();