Greasy Fork

Greasy Fork is available in English.

YouTube Ad Skipper

Automatically skip ads on YouTube with advanced options, performance improvements, and best video quality selection.

当前为 2024-08-09 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==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.0.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());
    }

    // 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');
          const highestQuality = qualityOptions[1]; // Second option is usually the highest available quality
          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();
})();