Greasy Fork is available in English.
Aggressively blocks YouTube ads and attempts to suppress the AdBlock warning by forcing the player state and instantly hiding the modal.
// ==UserScript==
// @name RafBlocker
// @namespace http://tampermonkey.net/
// @version 1.2
// @description Aggressively blocks YouTube ads and attempts to suppress the AdBlock warning by forcing the player state and instantly hiding the modal.
// @author Raf
// @match *://www.youtube.com/*
// @grant none
// @run-at document-idle
// @license MIT
// ==/UserScript==
/*
* MIT License
*
* Copyright (c) 2025 Raf (or your chosen name)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
(function() {
'use strict';
// --- Configuration and Selectors ---
const AD_CONTAINER_SELECTOR = '.ad-container, .video-ads, .ytp-ad-module';
const SKIP_BUTTON_SELECTOR = '.ytp-ad-skip-button, .ytp-skip-ad-button';
const AD_OVERLAY_SELECTOR = '.ytp-player-content-container .ytp-ce-element, .ytp-ad-overlay-container, .ytp-ad-image-overlay';
// Aggressive selectors for the warning modal and backdrop
const WARNING_MODAL_SELECTOR = 'ytd-popup-container, #popup, .yt-spec-general-modal, tp-yt-paper-dialog';
const DISMISS_BUTTON_SELECTOR = 'ytd-button-renderer button.ytd-popup-container, ytd-button-renderer button.yt-spec-general-modal';
// --- Core Functions ---
// Function to remove elements from the DOM
function removeElement(selector) {
document.querySelectorAll(selector).forEach(element => {
if (element) {
element.remove();
}
});
}
// Function to skip the video ad (works on pre-roll/mid-roll)
function skipVideoAd() {
const skipButton = document.querySelector(SKIP_BUTTON_SELECTOR);
if (skipButton) {
skipButton.click();
return true;
}
const videoPlayer = document.querySelector('video');
const adShowing = document.querySelector('.ad-showing');
// Check if an ad is clearly marked as playing and try to jump to the end
if (videoPlayer && adShowing) {
videoPlayer.currentTime = videoPlayer.duration;
return true;
}
return false;
}
// --- Ad Block Warning Evasion (The Core Fix) ---
function evadeAdDetection() {
// 1. Aggressively Hide the Modal and Backdrop via CSS
let style = document.getElementById('RafBlockerStyle');
if (!style) {
style = document.createElement('style');
style.id = 'RafBlockerStyle';
style.type = 'text/css';
document.head.appendChild(style);
}
// Keep the modal hidden and restore scrolling
style.innerHTML = `
${WARNING_MODAL_SELECTOR} {
display: none !important;
visibility: hidden !important;
}
body {
overflow: auto !important;
}
`;
// 2. Click any hidden dismiss buttons just in case
document.querySelectorAll(DISMISS_BUTTON_SELECTOR).forEach(button => {
if (button.innerText.toUpperCase().includes('DISMISS') || button.innerText.toUpperCase().includes('CLOSE')) {
button.click();
}
});
// 3. Forcing Player State (Most important part for persistent warnings)
// This attempts to trick YouTube's internal ad-check functions.
if (window.ytplayer) {
// Force the player to believe the ad has timed out or is already skipped
if (window.ytplayer.config.args) {
window.ytplayer.config.args.advideo = 0; // Standard ad flag
window.ytplayer.config.args.is_ad = false; // Is Ad flag
window.ytplayer.config.args.ad_flags = 0; // Ad flags
}
// Also check for the global Player object (if available)
const player = document.querySelector('#movie_player');
if (player && player.getPlayerState) {
// If the player is paused (state 2) due to the warning, try to play it (state 1 is playing)
if (player.getPlayerState() === 2) {
player.playVideo();
}
}
}
}
// --- Main Blocking Loop ---
function blockAdsAndWarning() {
// Always run evasion first to catch the warning instantly
evadeAdDetection();
// Standard ad removal
removeElement(AD_CONTAINER_SELECTOR);
removeElement(AD_OVERLAY_SELECTOR);
// Attempt to skip the video ad
skipVideoAd();
}
// Use a MutationObserver for dynamic content loading
const observer = new MutationObserver((mutations, obs) => {
// Only run the logic if we're on a YouTube page
blockAdsAndWarning();
});
// Start observing the body for changes
observer.observe(document.body, { childList: true, subtree: true });
// Also run blockAdsAndWarning on a rapid interval for aggressive ad/warning removal
setInterval(blockAdsAndWarning, 100); // Check every 100 milliseconds for maximum speed
})();