Greasy Fork

Greasy Fork is available in English.

YouTube Ad Skipper

Automatically skip ads on YouTube with advanced options and performance improvements

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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