Size
5.7 KB
Version
1.0.1
Created
Nov 18, 2025
Updated
3 months ago
1// ==UserScript==
2// @name YouTube Ad Blocker
3// @description Blocks all YouTube ads, banners, and promotional content
4// @version 1.0.1
5// @match https://*.youtube.com/*
6// @icon https://www.youtube.com/s/desktop/9c0f82da/img/favicon_32x32.png
7// @grant GM.addStyle
8// ==/UserScript==
9(function() {
10 'use strict';
11
12 console.log('YouTube Ad Blocker initialized');
13
14 // Add CSS to hide ad elements
15 const adBlockStyles = `
16 /* Hide video ads */
17 .video-ads,
18 .ytp-ad-module,
19 .ytp-ad-overlay-container,
20 .ytp-ad-text-overlay,
21 .ytp-ad-player-overlay,
22 .ytp-ad-image-overlay,
23 .ytp-ad-overlay-close-button,
24 ytd-display-ad-renderer,
25 ytd-promoted-sparkles-web-renderer,
26 ytd-promoted-video-renderer,
27 ytd-compact-promoted-video-renderer,
28 ytd-promoted-sparkles-text-search-renderer,
29
30 /* Hide banner ads */
31 ytd-banner-promo-renderer,
32 ytd-statement-banner-renderer,
33 ytd-in-feed-ad-layout-renderer,
34 ytd-ad-slot-renderer,
35 yt-mealbar-promo-renderer,
36 ytd-popup-container,
37 tp-yt-paper-dialog,
38
39 /* Hide masthead ads */
40 #masthead-ad,
41 ytd-rich-item-renderer.ytd-rich-grid-renderer:has(ytd-display-ad-renderer),
42
43 /* Hide sidebar ads */
44 #player-ads,
45 #panels:has(ytd-engagement-panel-section-list-renderer[target-id="engagement-panel-ads"]),
46
47 /* Hide overlay ads */
48 .ytp-ad-overlay-container,
49 .ytp-ad-overlay-image,
50
51 /* Hide companion ads */
52 #companion,
53 #companion-ad,
54
55 /* Hide premium prompts */
56 ytd-popup-container:has(ytd-premium-promo-renderer),
57 ytd-mealbar-promo-renderer,
58
59 /* Hide shorts ads */
60 ytd-reel-video-renderer:has(ytd-ad-slot-renderer),
61
62 /* Hide search ads */
63 ytd-search-pyv-renderer,
64 ytd-ad-slot-renderer[is-premiere],
65
66 /* Additional ad containers */
67 .ytd-display-ad-renderer,
68 .ytd-statement-banner-renderer,
69 .ytd-in-feed-ad-layout-renderer {
70 display: none !important;
71 visibility: hidden !important;
72 height: 0 !important;
73 min-height: 0 !important;
74 opacity: 0 !important;
75 }
76 `;
77
78 // Inject CSS styles
79 TM_addStyle(adBlockStyles);
80
81 // Function to skip video ads
82 function skipVideoAd() {
83 const video = document.querySelector('video.html5-main-video');
84 const skipButton = document.querySelector('.ytp-ad-skip-button, .ytp-skip-ad-button');
85 const adModule = document.querySelector('.ytp-ad-module');
86
87 // Click skip button if available
88 if (skipButton && skipButton.offsetParent !== null) {
89 console.log('Clicking skip ad button');
90 skipButton.click();
91 }
92
93 // Fast forward through ad if playing
94 if (video && adModule && adModule.offsetParent !== null) {
95 console.log('Fast forwarding through ad');
96 video.currentTime = video.duration;
97 video.playbackRate = 16;
98 }
99 }
100
101 // Function to remove ad elements from DOM
102 function removeAdElements() {
103 const adSelectors = [
104 'ytd-display-ad-renderer',
105 'ytd-promoted-sparkles-web-renderer',
106 'ytd-promoted-video-renderer',
107 'ytd-compact-promoted-video-renderer',
108 'ytd-banner-promo-renderer',
109 'ytd-statement-banner-renderer',
110 'ytd-in-feed-ad-layout-renderer',
111 'ytd-ad-slot-renderer',
112 'yt-mealbar-promo-renderer',
113 '.video-ads',
114 '.ytp-ad-module',
115 '#player-ads'
116 ];
117
118 adSelectors.forEach(selector => {
119 const elements = document.querySelectorAll(selector);
120 elements.forEach(el => {
121 if (el && el.parentNode) {
122 console.log('Removing ad element:', selector);
123 el.remove();
124 }
125 });
126 });
127 }
128
129 // Debounce function to prevent excessive calls
130 function debounce(func, wait) {
131 let timeout;
132 return function executedFunction(...args) {
133 const later = () => {
134 clearTimeout(timeout);
135 func(...args);
136 };
137 clearTimeout(timeout);
138 timeout = setTimeout(later, wait);
139 };
140 }
141
142 // Debounced ad removal
143 const debouncedRemoveAds = debounce(() => {
144 removeAdElements();
145 skipVideoAd();
146 }, 500);
147
148 // Watch for ad elements being added to the page
149 const observer = new MutationObserver(debouncedRemoveAds);
150
151 // Start observing when body is ready
152 TM_runBody(() => {
153 console.log('Starting ad blocker observer');
154
155 // Initial cleanup
156 removeAdElements();
157 skipVideoAd();
158
159 // Observe DOM changes
160 observer.observe(document.body, {
161 childList: true,
162 subtree: true
163 });
164
165 // Check for video ads every second
166 setInterval(() => {
167 skipVideoAd();
168 }, 1000);
169
170 // Remove ads on navigation (YouTube is a SPA)
171 let lastUrl = location.href;
172 new MutationObserver(() => {
173 const currentUrl = location.href;
174 if (currentUrl !== lastUrl) {
175 lastUrl = currentUrl;
176 console.log('Page navigation detected, removing ads');
177 setTimeout(() => {
178 removeAdElements();
179 }, 1000);
180 }
181 }).observe(document.body, { subtree: true, childList: true });
182 });
183
184 console.log('YouTube Ad Blocker loaded successfully');
185})();