// ==UserScript== // @name YouTube Ad Skipper // @name:en YouTube Ad Skipper // @name:vi YouTube Ad Skipper // @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 2.2.0 // @description Automatically skip ads on YouTube with advanced options, performance improvements, and best video quality selection. // @description:en Automatically skip ads on YouTube with advanced options, performance improvements, and best video quality selection. // @description:vi Tự động bỏ qua quảng cáo trên YouTube với các tùy chọn nâng cao, cải thiện hiệu suất và lựa chọn chất lượng video tốt nhất. // @description:zh-cn 自动跳过 YouTube 上的广告,提供高级选项、性能改进和最佳视频质量选择。 // @description:zh-tw 自動跳過 YouTube 上的廣告,提供進階選項、效能改進和最佳影片品質選擇。 // @description:ja YouTube の広告を自動的にスキップし、高度なオプション、パフォーマンスの向上、最高のビデオ品質の選択を提供します。 // @description:ko YouTube에서 광고를 자동으로 건너뛰고 고급 옵션, 성능 향상 및 최상의 비디오 품질 선택을 제공합니다。 // @description:es Omite automáticamente los anuncios en YouTube con opciones avanzadas, mejoras de rendimiento y selección de la mejor calidad de video. // @description:ru Автоматически пропускает рекламу на YouTube с расширенными настройками, улучшением производительности и выбором наилучшего качества видео. // @description:id Lewati iklan secara otomatis di YouTube dengan opsi lanjutan, peningkatan kinerja, dan pemilihan kualitas video terbaik. // @description:hi YouTube पर विज्ञापनों को स्वचालित रूप से छोड़ें, उन्नत विकल्पों, प्रदर्शन में सुधार और सर्वोत्तम वीडियो गुणवत्ता चयन के साथ। // @author Jann // @license MIT // @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com // @match https://*.youtube.com/* // @grant GM_setValue // @grant GM_getValue // @grant GM_registerMenuCommand // @grant GM_addStyle // @downloadURL none // ==/UserScript== (function() { 'use strict'; const DEFAULT_CONFIG = { skipInterval: 250, observerThrottle: 500, muteAds: false, hideAdOverlays: true, removeAdSlots: true, autoHideAnnotations: true, disableAutoplay: false, improvePerformance: true, autoSelectBestQuality: true, performance: { hideComments: true, hideSidebar: true, disableAnimations: true, lazyLoadImages: true, reduceScriptExecution: true } }; let config = { ...DEFAULT_CONFIG, ...GM_getValue('AdSkipperConfig', {}) }; 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 = { ...DEFAULT_CONFIG, ...JSON.parse(newConfig) }; saveConfig(); alert("Configuration updated successfully!"); location.reload(); } catch (e) { alert("Error: Invalid configuration format!"); } } }); } function skipAds() { const video = document.querySelector('video'); // Improved ad detection const adIndicators = [ '.ytp-ad-skip-button', '.ytp-ad-skip-button-modern', '.ad-showing', '.ytp-ad-overlay-close-button', '.ytp-ad-overlay-image', 'ytd-ad-slot-renderer', 'ytm-promoted-video-renderer', '[id^="ad-text"]', '[id^="ad-image"]' ]; const isAdPresent = adIndicators.some(selector => document.querySelector(selector)); if (isAdPresent) { // Skip ads using the skip button document.querySelectorAll('.ytp-ad-skip-button, .ytp-ad-skip-button-modern').forEach(button => button.click()); // Skip ads by seeking to the end if (video && document.querySelector('.ad-showing')) { video.currentTime = video.duration; video.muted = config.muteAds; } // Hide ad overlays if (config.hideAdOverlays) { document.querySelectorAll('.ytp-ad-overlay-close-button').forEach(button => button.click()); document.querySelectorAll('.ytp-ad-overlay-image').forEach(overlay => overlay.style.display = 'none'); } // Remove ad slots if (config.removeAdSlots) { document.querySelectorAll('ytd-ad-slot-renderer, ytm-promoted-video-renderer').forEach(slot => { slot.style.display = 'none'; }); } } // Auto-hide annotations if (config.autoHideAnnotations) { document.querySelectorAll('.ytp-ce-covering-overlay').forEach(overlay => overlay.style.display = 'none'); } // Disable autoplay if (config.disableAutoplay) { const autoplayToggle = document.querySelector('.ytp-autonav-toggle-button[aria-checked="true"]'); if (autoplayToggle) autoplayToggle.click(); } } const throttle = (func, limit) => { let lastFunc; let lastRan; return function() { const context = this; const args = arguments; if (!lastRan) { func.apply(context, args); lastRan = Date.now(); } else { clearTimeout(lastFunc); lastFunc = setTimeout(function() { if ((Date.now() - lastRan) >= limit) { func.apply(context, args); lastRan = Date.now(); } }, limit - (Date.now() - lastRan)); } } }; const throttledSkipAds = throttle(skipAds, config.observerThrottle); const observer = new MutationObserver(throttledSkipAds); observer.observe(document.body, { childList: true, subtree: true }); function setMaxVideoQuality() { if (!config.autoSelectBestQuality) return; const qualityMenu = document.querySelector('.ytp-settings-button'); if (qualityMenu) { qualityMenu.click(); setTimeout(() => { const qualitySettings = document.querySelector('.ytp-panel-menu'); if (qualitySettings) { const qualityOptions = Array.from(qualitySettings.querySelectorAll('.ytp-menuitem')); const highestQuality = qualityOptions.reduce((highest, current) => { const resolution = current.textContent.trim().match(/(\d+)p/); const currentResolution = resolution ? parseInt(resolution[1]) : 0; const highestResolution = highest.textContent.trim().match(/(\d+)p/); return currentResolution > (highestResolution ? parseInt(highestResolution[1]) : 0) ? current : highest; }, qualityOptions[0]); if (highestQuality) { highestQuality.click(); } } qualityMenu.click(); // Close the menu }, 100); } } function applyPerformanceImprovements() { if (!config.improvePerformance) return; const styles = ` ${config.performance.hideSidebar ? ` .ytd-watch-flexy:not([theater]) #secondary.ytd-watch-flexy, ytd-watch-next-secondary-results-renderer { display: none !important; } ` : ''} ${config.performance.hideComments ? ` #comments { display: none !important; } ` : ''} ${config.performance.disableAnimations ? ` * { transition: none !important; animation: none !important; } ` : ''} ${config.performance.reduceScriptExecution ? ` .ytp-ce-element { display: none !important; } ` : ''} `; GM_addStyle(styles); if (config.performance.lazyLoadImages) { document.addEventListener('DOMContentLoaded', () => { document.querySelectorAll('img').forEach(img => { img.loading = 'lazy'; }); }); } if (config.performance.reduceScriptExecution) { let ticking = false; window.addEventListener('scroll', () => { if (!ticking) { window.requestAnimationFrame(() => { // Handle scroll event here ticking = false; }); ticking = true; } }); let resizeTimer; window.addEventListener('resize', () => { clearTimeout(resizeTimer); resizeTimer = setTimeout(() => { // Handle resize event here }, 250); }); } } function init() { setInterval(skipAds, config.skipInterval); setInterval(setMaxVideoQuality, 5000); applyPerformanceImprovements(); createSettingsMenu(); } init(); })();