Greasy Fork

Greasy Fork is available in English.

YouTube Ad Skipper

Automatically skip ads on YouTube with advanced options and performance improvements. Also automatically selects the best video quality.

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

您需要先安装一款用户脚本管理器扩展,例如 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          Saltador de Anuncios de YouTube Mejorado
// @name:ru          Улучшенный пропуск рекламы на YouTube
// @name:id          YouTube Ad Skipper
// @name:hi          YouTube विज्ञापन स्किपर
// @namespace        http://tampermonkey.net/
// @version          1.6.0
// @description      Automatically skip ads on YouTube with advanced options and performance improvements. Also automatically selects the best video quality.
// @description:en   Automatically skip ads on YouTube with advanced options and performance improvements. Also automatically selects the best video quality.
// @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. Đồng thời tự động 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   Salta automáticamente los anuncios en YouTube con opciones avanzadas y mejoras de rendimiento. También selecciona automáticamente la mejor calidad de video.
// @description:ru   Автоматически пропускает рекламу на YouTube с расширенными настройками и улучшенной производительностью. Также автоматически выбирает наилучшее качество видео.
// @description:id   Lewati iklan secara otomatis di YouTube dengan opsi lanjutan dan peningkatan kinerja. Juga secara otomatis memilih kualitas video terbaik.
// @description:hi   उन्नत विकल्पों और प्रदर्शन सुधारों के साथ YouTube पर विज्ञापनों को स्वचालित रूप से छोड़ें। साथ ही स्वचालित रूप से सर्वोत्तम वीडियो गुणवत्ता का चयन करें।
// @author           Jann
// @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';

  const DEFAULT_CONFIG = {
    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 = { ...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;
      if (config.muteAds) video.muted = true;
    }

    // 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 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,
      ytd-watch-next-secondary-results-renderer {
        display: none !important;
      }
    `);
  }

  // Automatically select the best video quality
  function setMaxVideoQuality() {
    const videoPlayer = document.querySelector('video');
    if (videoPlayer) {
      const availableQualities = videoPlayer.getElementsByTagName('source');
      if (availableQualities.length > 0) {
        let maxQuality = 0;
        let maxQualitySource = null;
        for (let i = 0; i < availableQualities.length; i++) {
          const quality = parseInt(availableQualities[i].size);
          if (quality > maxQuality) {
            maxQuality = quality;
            maxQualitySource = availableQualities[i];
          }
        }

        // Bypass premium quality
        for (let i = 0; i < availableQualities.length; i++) {
          if (availableQualities[i].label.includes('Premium')) {
            availableQualities[i].removeAttribute('disabled');
          }
        }

        if (maxQualitySource) {
          videoPlayer.src = maxQualitySource.src;
        }
      }
    }
  }


  setMaxVideoQuality();

  setInterval(setMaxVideoQuality, 2000);

  createSettingsMenu();
  })();