YouTube 廣告跳過器

在 YouTube 上自動跳過廣告,提供進階選項和效能改進。同時自動選擇最佳影片畫質。

目前為 2024-08-08 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name YouTube Ad Skipper
  3. // @name:en YouTube Ad Skipper
  4. // @name:vi Trình Tự Động Bỏ Qua Quảng Cáo YouTube
  5. // @name:zh-cn YouTube 广告跳过器
  6. // @name:zh-tw YouTube 廣告跳過器
  7. // @name:ja YouTube 広告スキッパー
  8. // @name:ko YouTube 광고 건너뛰기
  9. // @name:es Saltador de Anuncios de YouTube Mejorado
  10. // @name:ru Улучшенный пропуск рекламы на YouTube
  11. // @name:id YouTube Ad Skipper
  12. // @name:hi YouTube विज्ञापन स्किपर
  13. // @namespace http://tampermonkey.net/
  14. // @version 1.6.0
  15. // @description Automatically skip ads on YouTube with advanced options and performance improvements. Also automatically selects the best video quality.
  16. // @description:en Automatically skip ads on YouTube with advanced options and performance improvements. Also automatically selects the best video quality.
  17. // @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.
  18. // @description:zh-cn 在 YouTube 上自动跳过广告,提供高级选项和性能改进。同时自动选择最佳视频质量。
  19. // @description:zh-tw 在 YouTube 上自動跳過廣告,提供進階選項和效能改進。同時自動選擇最佳影片畫質。
  20. // @description:ja 高度なオプションとパフォーマンス向上を備えた YouTube の広告を自動的にスキップします。また、最高のビデオ品質を自動的に選択します。
  21. // @description:ko 고급 옵션 및 성능 개선으로 YouTube 광고를 자동으로 건너뛰고 최상의 비디오 품질을 자동으로 선택합니다.
  22. // @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.
  23. // @description:ru Автоматически пропускает рекламу на YouTube с расширенными настройками и улучшенной производительностью. Также автоматически выбирает наилучшее качество видео.
  24. // @description:id Lewati iklan secara otomatis di YouTube dengan opsi lanjutan dan peningkatan kinerja. Juga secara otomatis memilih kualitas video terbaik.
  25. // @description:hi उन्नत विकल्पों और प्रदर्शन सुधारों के साथ YouTube पर विज्ञापनों को स्वचालित रूप से छोड़ें। साथ ही स्वचालित रूप से सर्वोत्तम वीडियो गुणवत्ता का चयन करें।
  26. // @author Jann
  27. // @icon https://www.google.com/s2/favicons?domain=youtube.com
  28. // @license MIT
  29. // @match https://*.youtube.com/*
  30. // @grant GM_setValue
  31. // @grant GM_getValue
  32. // @grant GM_registerMenuCommand
  33. // @grant GM_addStyle
  34. // ==/UserScript==
  35.  
  36. (function () {
  37. 'use strict';
  38.  
  39. const DEFAULT_CONFIG = {
  40. skipInterval: 500,
  41. observerThrottle: 1000,
  42. 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.
  43. hideAdOverlays: true,
  44. removeAdSlots: true,
  45. autoHideAnnotations: true,
  46. disableAutoplay: false,
  47. improvePerformance: true
  48. };
  49.  
  50. let config = { ...DEFAULT_CONFIG, ...GM_getValue('AdSkipperConfig', {}) };
  51.  
  52. function saveConfig() {
  53. GM_setValue('AdSkipperConfig', config);
  54. }
  55.  
  56. function createSettingsMenu() {
  57. GM_registerMenuCommand("Configure Ad Skipper", () => {
  58. const newConfig = prompt("Enter new configuration (JSON):", JSON.stringify(config, null, 2));
  59. if (newConfig) {
  60. try {
  61. config = { ...DEFAULT_CONFIG, ...JSON.parse(newConfig) };
  62. saveConfig();
  63. alert("Configuration updated successfully!");
  64. location.reload();
  65. } catch (e) {
  66. alert("Error: Invalid configuration format!");
  67. }
  68. }
  69. });
  70. }
  71.  
  72. function skipAds() {
  73. const video = document.querySelector('video');
  74.  
  75. // Skip ads using the skip button
  76. document.querySelectorAll('.ytp-ad-skip-button, .ytp-ad-skip-button-modern').forEach(button => button.click());
  77.  
  78. // Skip ads by seeking to the end
  79. if (document.querySelector('.ad-showing') && video) {
  80. video.currentTime = video.duration;
  81. if (config.muteAds) video.muted = true;
  82. }
  83.  
  84. // Hide ad overlays
  85. if (config.hideAdOverlays) {
  86. document.querySelectorAll('.ytp-ad-overlay-close-button').forEach(button => button.click());
  87. }
  88.  
  89. // Remove ad slots
  90. if (config.removeAdSlots) {
  91. document.querySelectorAll('ytd-ad-slot-renderer, ytm-promoted-video-renderer').forEach(slot => {
  92. slot.style.display = 'none';
  93. });
  94. }
  95.  
  96. // Auto-hide annotations
  97. if (config.autoHideAnnotations) {
  98. document.querySelectorAll('.ytp-ce-covering-overlay').forEach(overlay => overlay.style.display = 'none');
  99. }
  100.  
  101. // Disable autoplay
  102. if (config.disableAutoplay) {
  103. const autoplayToggle = document.querySelector('.ytp-autonav-toggle-button[aria-checked="true"]');
  104. if (autoplayToggle) autoplayToggle.click();
  105. }
  106. }
  107.  
  108. function throttle(func, limit) {
  109. let inThrottle;
  110. return function() {
  111. const args = arguments;
  112. const context = this;
  113. if (!inThrottle) {
  114. func.apply(context, args);
  115. inThrottle = true;
  116. setTimeout(() => inThrottle = false, limit);
  117. }
  118. }
  119. }
  120.  
  121. const throttledSkipAds = throttle(skipAds, config.observerThrottle);
  122.  
  123. const observer = new MutationObserver(throttledSkipAds);
  124.  
  125. observer.observe(document.body, {
  126. childList: true,
  127. subtree: true
  128. });
  129.  
  130. setInterval(skipAds, config.skipInterval);
  131.  
  132. if (config.improvePerformance) {
  133. GM_addStyle(`
  134. .ytd-watch-flexy:not([theater]) #secondary.ytd-watch-flexy,
  135. ytd-watch-next-secondary-results-renderer {
  136. display: none !important;
  137. }
  138. `);
  139. }
  140.  
  141. // Automatically select the best video quality
  142. function setMaxVideoQuality() {
  143. const videoPlayer = document.querySelector('video');
  144. if (videoPlayer) {
  145. const availableQualities = videoPlayer.getElementsByTagName('source');
  146. if (availableQualities.length > 0) {
  147. let maxQuality = 0;
  148. let maxQualitySource = null;
  149. for (let i = 0; i < availableQualities.length; i++) {
  150. const quality = parseInt(availableQualities[i].size);
  151. if (quality > maxQuality) {
  152. maxQuality = quality;
  153. maxQualitySource = availableQualities[i];
  154. }
  155. }
  156.  
  157. // Bypass premium quality
  158. for (let i = 0; i < availableQualities.length; i++) {
  159. if (availableQualities[i].label.includes('Premium')) {
  160. availableQualities[i].removeAttribute('disabled');
  161. }
  162. }
  163.  
  164. if (maxQualitySource) {
  165. videoPlayer.src = maxQualitySource.src;
  166. }
  167. }
  168. }
  169. }
  170.  
  171.  
  172. setMaxVideoQuality();
  173.  
  174. setInterval(setMaxVideoQuality, 2000);
  175.  
  176. createSettingsMenu();
  177. })();