// ==UserScript== // @name YouTube Ad Skipper // @name:en YouTube Ad Skipper // @name:vi Trình 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 de Anuncios de YouTube Mejorado // @name:ru пропуск рекламы на YouTube // @name:id YouTube Ad Skipper // @name:hi YouTube विज्ञापन स्किपर // @namespace http://tampermonkey.net/ // @version 1.3.0 // @description Automatically skip ads on YouTube with advanced options and performance improvements // @description:en Automatically skip ads on YouTube with advanced options and performance improvements // @description:vi Tự động bỏ qua quảng cáo trên YouTube với các tùy chọn nâng cao và cải thiện hiệu suất // @description:zh-cn 在 YouTube 上自动跳过广告,提供高级选项和性能改进 // @description:zh-tw 在 YouTube 上自動跳過廣告,提供進階選項和效能改進 // @description:ja 高度なオプションとパフォーマンス向上を備えた YouTube の広告を自動的にスキップ // @description:ko 고급 옵션 및 성능 개선으로 YouTube 광고를 자동으로 건너뛰기 // @description:es Salta automáticamente los anuncios en YouTube con opciones avanzadas y mejoras de rendimiento // @description:ru Автоматически пропускает рекламу на YouTube с расширенными настройками и улучшенной производительностью // @description:id Lewati iklan secara otomatis di YouTube dengan opsi lanjutan dan peningkatan kinerja // @description:hi उन्नत विकल्पों और प्रदर्शन सुधारों के साथ YouTube पर विज्ञापनों को स्वचालित रूप से छोड़ें // @author Jann (Enhanced by Assistant) // @icon https://www.google.com/s2/favicons?domain=youtube.com // @license MIT // @match https://*.youtube.com/* // @grant GM_setValue // @grant GM_getValue // @grant GM_registerMenuCommand // @grant GM_addStyle // @downloadURL none // ==/UserScript== (function () { 'use strict'; // Configuration const defaultConfig = { skipInterval: 500, observerThrottle: 1000, muteAds: false, // Leave it as the default false. I recommend keeping it false because setting it to true, while muting ads, can also cause the video's audio to be muted as a side effect. hideAdOverlays: true, removeAdSlots: true, autoHideAnnotations: true, disableAutoplay: false, improvePerformance: true }; let config = GM_getValue('AdSkipperConfig', defaultConfig); function saveConfig() { GM_setValue('AdSkipperConfig', config); } function createSettingsMenu() { GM_registerMenuCommand("Configure Ad Skipper", () => { const newConfig = prompt("Enter new configuration (JSON):", JSON.stringify(config, null, 2)); if (newConfig) { try { config = { ...defaultConfig, ...JSON.parse(newConfig) }; saveConfig(); alert("Configuration updated successfully!"); location.reload(); } catch (e) { alert("Error: Invalid configuration format!"); } } }); } 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'; }); } if (config.autoHideAnnotations) { const annotationToggle = document.querySelector('.ytp-ce-covering-overlay'); if (annotationToggle) { annotationToggle.style.display = 'none'; } } if (config.disableAutoplay) { const autoplayToggle = document.querySelector('.ytp-autonav-toggle-button'); if (autoplayToggle && autoplayToggle.getAttribute('aria-checked') === 'true') { autoplayToggle.click(); } } } function throttle(func, limit) { let inThrottle; return function () { const args = arguments; const context = this; if (!inThrottle) { func.apply(context, args); inThrottle = true; setTimeout(() => inThrottle = false, limit); } } } const throttledSkipAds = throttle(skipAds, config.observerThrottle); const observer = new MutationObserver(throttledSkipAds); observer.observe(document.body, { childList: true, subtree: true }); setInterval(skipAds, config.skipInterval); if (config.improvePerformance) { GM_addStyle(` .ytd-watch-flexy:not([theater]) #secondary.ytd-watch-flexy { display: none !important; } ytd-watch-next-secondary-results-renderer { display: none !important; } `); } createSettingsMenu(); })();