// ==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.1.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
// ==/UserScript==
// This userscript automatically skips ads on YouTube, providing options for
// performance enhancements and selecting the best video quality.
// Features:
// - Automatically skips ads by clicking the skip button or seeking to the end.
// - Mutes ads (optional).
// - Hides ad overlays (optional).
// - Removes ad slots from the page (optional).
// - Auto-hides annotations (optional).
// - Disables autoplay (optional).
// - Improves performance by hiding comments, sidebar, disabling animations,
// lazy-loading images, and reducing script execution (optional).
// - Automatically selects the best video quality (optional).
// - Provides a configurable settings menu accessible through the Tampermonkey menu.
// Configuration:
// The script can be configured through a JSON object in the settings menu.
// The following options are available:
// - `skipInterval`: Interval (in milliseconds) to check for ads. (Default: 500)
// - `observerThrottle`: Throttle time (in milliseconds) for the mutation observer. (Default: 1000)
// - `muteAds`: Mute ads during playback. (Default: false)
// - `hideAdOverlays`: Hide ad overlays that appear on top of the video. (Default: true)
// - `removeAdSlots`: Remove ad slots from the page entirely. (Default: true)
// - `autoHideAnnotations`: Automatically hide annotations that appear on the video. (Default: true)
// - `disableAutoplay`: Disable the autoplay feature on YouTube. (Default: false)
// - `improvePerformance`: Enable performance improvements. (Default: true)
// - `autoSelectBestQuality`: Automatically select the best available video quality. (Default: true)
// - `performance`: Object containing performance-related settings:
// - `hideComments`: Hide the comments section. (Default: true)
// - `hideSidebar`: Hide the sidebar on the watch page. (Default: true)
// - `disableAnimations`: Disable animations on the page. (Default: true)
// - `lazyLoadImages`: Lazy-load images to improve initial page load time. (Default: true)
// - `reduceScriptExecution`: Reduce the execution of unnecessary scripts. (Default: true)
// How to use:
// 1. Install a userscript manager like Tampermonkey or Greasemonkey.
// 2. Copy and paste this script into the userscript manager.
// 3. Visit YouTube and enjoy ad-free viewing.
// To configure the script:
// 1. Open the Tampermonkey/Greasemonkey menu.
// 2. Click on "YouTube Ad Skipper".
// 3. Click on "Configure Ad Skipper".
// 4. A prompt will appear with the current configuration in JSON format.
// 5. Modify the configuration as desired and click "OK".
// Note: This script is provided as-is and may not work with all versions of YouTube.
// Use it at your own risk.
// --- Code starts below ---
(function () {
'use strict';
const DEFAULT_CONFIG = {
skipInterval: 500,
observerThrottle: 1000,
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');
// 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 (document.querySelector('.ad-showing') && video) {
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'); // Hide image overlays
}
// 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();
}
}
function 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 = qualitySettings.querySelectorAll('.ytp-menuitem');
let highestQuality = qualityOptions[qualityOptions.length - 1]; // Select the last option, which is usually the highest
// Iterate through options and select the one with the highest resolution
qualityOptions.forEach(option => {
const resolution = option.textContent.trim().match(/\d+p/);
if (resolution) {
const currentResolution = parseInt(resolution[0].slice(0, -1));
const highestResolution = parseInt(highestQuality.textContent.trim().match(/\d+p/)[0].slice(0, -1));
if (currentResolution > highestResolution) {
highestQuality = option;
}
}
});
if (highestQuality) {
highestQuality.click();
}
}
qualityMenu.click(); // Close the menu
}, 100);
}
}
function applyPerformanceImprovements() {
if (!config.improvePerformance) return;
let styles = '';
if (config.performance.hideSidebar) {
styles += `
.ytd-watch-flexy:not([theater]) #secondary.ytd-watch-flexy,
ytd-watch-next-secondary-results-renderer {
display: none !important;
}
`;
}
if (config.performance.hideComments) {
styles += `
#comments {
display: none !important;
}
`;
}
if (config.performance.disableAnimations) {
styles += `
* {
transition: none !important;
animation: none !important;
}
`;
}
if (config.performance.lazyLoadImages) {
document.addEventListener('DOMContentLoaded', () => {
const images = document.querySelectorAll('img');
images.forEach(img => {
img.loading = 'lazy';
});
});
}
if (config.performance.reduceScriptExecution) {
// Disable certain YouTube features that might be script-heavy
styles += `
.ytp-ce-element {
display: none !important;
}
`;
}
GM_addStyle(styles);
// Additional performance improvements
if (config.performance.reduceScriptExecution) {
// Throttle scroll events
let ticking = false;
window.addEventListener('scroll', function(e) {
if (!ticking) {
window.requestAnimationFrame(function() {
// Handle scroll event here
ticking = false;
});
ticking = true;
}
});
// Debounce resize events
let resizeTimer;
window.addEventListener('resize', function(e) {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(function() {
// Handle resize event here
}, 250);
});
}
}
function init() {
setInterval(skipAds, config.skipInterval);
setInterval(setMaxVideoQuality, 5000);
applyPerformanceImprovements();
createSettingsMenu();
}
init();
})();