// ==UserScript== // @name YouTube Ad Skipper // @name:en YouTube Ad Skipper // @name:vi 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 YouTube Ad Skipper // @name:ru Пропуск рекламы на YouTube // @name:id YouTube Ad Skipper // @name:hi YouTube विज्ञापन स्किपर // @namespace http://tampermonkey.net/ // @version 1.2.1 // @description Automatically skip ads on YouTube with various options // @description:en Automatically skip ads on YouTube with various options // @description:vi Tự động bỏ qua quảng cáo trên YouTube với nhiều tùy chọn // @description:zh-cn 在 YouTube 上自动跳过广告,提供多种选项 // @description:zh-tw 在 YouTube 上自動跳過廣告,提供多種選項 // @description:ja さまざまなオプションで YouTube の広告を自動的にスキップします // @description:ko 다양한 옵션으로 YouTube 광고를 자동으로 건너뜁니다 // @description:es Salta automáticamente los anuncios en YouTube con varias opciones // @description:ru Автоматически пропускает рекламу на YouTube с различными настройками // @description:id Lewati iklan secara otomatis di YouTube dengan berbagai opsi // @description:hi विभिन्न विकल्पों के साथ YouTube पर विज्ञापनों को स्वचालित रूप से छोड़ें // @author Jann // @icon https://t2.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=http://youtube.com&size=64 // @license MIT // @match https://*.youtube.com/* // @grant GM_setValue // @grant GM_getValue // @grant GM_registerMenuCommand // @downloadURL none // ==/UserScript== (function() { 'use strict'; // Configuration default const defaultConfig = { skipInterval: 500, observerThrottle: 1000, muteAds: false, hideAdOverlays: true, removeAdSlots: true }; let config = GM_getValue('adSkipperConfig', defaultConfig); function saveConfig() { GM_setValue('adSkipperConfig', config); } function createSettingsMenu() { GM_registerMenuCommand("Configuration Ad Skipper", () => { const newConfig = prompt("Import new configuration (JSON):", JSON.stringify(config, null, 2)); if (newConfig) { try { config = JSON.parse(newConfig); saveConfig(); alert("Configuration has been updated!"); } catch (e) { alert("Error: Invalid configuration!"); } } }); } 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'; }); } } function debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } const debouncedSkipAds = debounce(skipAds, config.observerThrottle); const observer = new MutationObserver(debouncedSkipAds); observer.observe(document.body, { childList: true, subtree: true }); setInterval(skipAds, config.skipInterval); createSettingsMenu(); })();