Size
4.4 KB
Version
1.0.1
Created
Mar 4, 2026
Updated
about 1 month ago
1// ==UserScript==
2// @name YouTube Ad Blocker
3// @description Blocks ads on YouTube videos and pages
4// @version 1.0.1
5// @match https://*.youtube.com/*
6// @icon https://www.youtube.com/s/desktop/ce9675e8/img/favicon_32x32.png
7// ==/UserScript==
8(function() {
9 'use strict';
10
11 console.log('YouTube Ad Blocker initialized');
12
13 // Debounce function to prevent excessive calls
14 function debounce(func, wait) {
15 let timeout;
16 return function executedFunction(...args) {
17 const later = () => {
18 clearTimeout(timeout);
19 func(...args);
20 };
21 clearTimeout(timeout);
22 timeout = setTimeout(later, wait);
23 };
24 }
25
26 // Function to remove ads from the page
27 function removeAds() {
28 let adsRemoved = 0;
29
30 // Remove video ads and ad containers
31 const adSelectors = [
32 'ytd-ad-slot-renderer',
33 'ytd-in-feed-ad-layout-renderer',
34 'ytd-banner-promo-renderer',
35 'ytd-video-masthead-ad-v3-renderer',
36 'ytd-statement-banner-renderer',
37 'ytd-action-companion-ad-renderer',
38 'ytd-display-ad-renderer',
39 'ytd-promoted-sparkles-web-renderer',
40 '.video-ads',
41 '.ytp-ad-module',
42 '.ytp-ad-overlay-container',
43 '.ytp-ad-text-overlay',
44 'ytd-compact-promoted-item-renderer',
45 'ytd-promoted-video-renderer'
46 ];
47
48 adSelectors.forEach(selector => {
49 const ads = document.querySelectorAll(selector);
50 ads.forEach(ad => {
51 if (ad && ad.parentElement) {
52 console.log(`Removing ad element: ${selector}`);
53 ad.remove();
54 adsRemoved++;
55 }
56 });
57 });
58
59 // Skip video ads by detecting and clicking skip button
60 const skipButton = document.querySelector('.ytp-ad-skip-button, .ytp-skip-ad-button');
61 if (skipButton) {
62 console.log('Clicking skip ad button');
63 skipButton.click();
64 adsRemoved++;
65 }
66
67 // Remove overlay ads on videos
68 const overlayAds = document.querySelectorAll('.ytp-ad-overlay-close-button');
69 overlayAds.forEach(closeBtn => {
70 console.log('Closing overlay ad');
71 closeBtn.click();
72 adsRemoved++;
73 });
74
75 if (adsRemoved > 0) {
76 console.log(`Total ads removed: ${adsRemoved}`);
77 }
78 }
79
80 // Function to speed up video ads if they can't be skipped
81 function speedUpVideoAds() {
82 const video = document.querySelector('video');
83 if (video) {
84 const adPlaying = document.querySelector('.ad-showing, .ytp-ad-player-overlay');
85 if (adPlaying) {
86 console.log('Ad detected, speeding up video');
87 video.playbackRate = 16; // Maximum speed
88 video.muted = true;
89 }
90 }
91 }
92
93 // Add CSS to hide ads
94 const style = document.createElement('style');
95 style.textContent = `
96 ytd-ad-slot-renderer,
97 ytd-in-feed-ad-layout-renderer,
98 ytd-banner-promo-renderer,
99 ytd-video-masthead-ad-v3-renderer,
100 ytd-statement-banner-renderer,
101 ytd-action-companion-ad-renderer,
102 ytd-display-ad-renderer,
103 ytd-promoted-sparkles-web-renderer,
104 ytd-compact-promoted-item-renderer,
105 ytd-promoted-video-renderer,
106 .video-ads,
107 .ytp-ad-module,
108 .ytp-ad-overlay-container,
109 .ytp-ad-text-overlay {
110 display: none !important;
111 visibility: hidden !important;
112 height: 0 !important;
113 width: 0 !important;
114 opacity: 0 !important;
115 }
116 `;
117 document.head.appendChild(style);
118 console.log('Ad blocking CSS injected');
119
120 // Initial ad removal
121 removeAds();
122
123 // Create debounced version of removeAds
124 const debouncedRemoveAds = debounce(removeAds, 500);
125
126 // Watch for DOM changes to catch dynamically loaded ads
127 const observer = new MutationObserver(debouncedRemoveAds);
128
129 observer.observe(document.body, {
130 childList: true,
131 subtree: true
132 });
133
134 console.log('MutationObserver started watching for ads');
135
136 // Periodically check for video ads and speed them up
137 setInterval(() => {
138 removeAds();
139 speedUpVideoAds();
140 }, 1000);
141
142 console.log('YouTube Ad Blocker is now active');
143})();