自动跳过 YouTube 广告

立即自动跳过 YouTube 广告。不会被 YouTube 广告拦截器警告检测到。

安装此脚本
作者推荐脚本

您可能也喜欢YouTube Shorts 转普通视频

安装此脚本
  1. // ==UserScript==
  2. // @name Auto Skip YouTube Ads
  3. // @name:ar تخطي إعلانات YouTube تلقائيًا
  4. // @name:es Saltar Automáticamente Anuncios De YouTube
  5. // @name:fr Ignorer Automatiquement Les Publicités YouTube
  6. // @name:hi YouTube विज्ञापन स्वचालित रूप से छोड़ें
  7. // @name:id Lewati Otomatis Iklan YouTube
  8. // @name:ja YouTube 広告を自動スキップ
  9. // @name:ko YouTube 광고 자동 건너뛰기
  10. // @name:nl YouTube-Advertenties Automatisch Overslaan
  11. // @name:pt-BR Pular Automaticamente Anúncios Do YouTube
  12. // @name:ru Автоматический Пропуск Рекламы На YouTube
  13. // @name:vi Tự Động Bỏ Qua Quảng Cáo YouTube
  14. // @name:zh-CN 自动跳过 YouTube 广告
  15. // @name:zh-TW 自動跳過 YouTube 廣告
  16. // @namespace https://github.com/tientq64/userscripts
  17. // @version 7.3.0
  18. // @description Automatically skip YouTube ads instantly. Undetected by YouTube ad blocker warnings.
  19. // @description:ar تخطي إعلانات YouTube تلقائيًا على الفور. دون أن يتم اكتشاف ذلك من خلال تحذيرات أداة حظر الإعلانات في YouTube.
  20. // @description:es Omite automáticamente los anuncios de YouTube al instante. Sin que te detecten las advertencias del bloqueador de anuncios de YouTube.
  21. // @description:fr Ignorez automatiquement et instantanément les publicités YouTube. Non détecté par les avertissements du bloqueur de publicités YouTube.
  22. // @description:hi YouTube विज्ञापनों को स्वचालित रूप से तुरंत छोड़ दें। YouTube विज्ञापन अवरोधक चेतावनियों द्वारा पता नहीं लगाया गया।
  23. // @description:id Lewati iklan YouTube secara otomatis secara instan. Tidak terdeteksi oleh peringatan pemblokir iklan YouTube.
  24. // @description:ja YouTube 広告を即座に自動的にスキップします。YouTube 広告ブロッカーの警告には検出されません。
  25. // @description:ko YouTube 광고를 즉시 자동으로 건너뜁니다. YouTube 광고 차단 경고에 감지되지 않습니다.
  26. // @description:nl Sla YouTube-advertenties direct automatisch over. Ongemerkt door YouTube-adblockerwaarschuwingen.
  27. // @description:pt-BR Pule anúncios do YouTube instantaneamente. Não detectado pelos avisos do bloqueador de anúncios do YouTube.
  28. // @description:ru Автоматически пропускать рекламу YouTube мгновенно. Не обнаруживается предупреждениями блокировщиков рекламы YouTube.
  29. // @description:vi Tự động bỏ qua quảng cáo YouTube ngay lập tức. Không bị phát hiện bởi cảnh báo trình chặn quảng cáo của YouTube.
  30. // @description:zh-CN 立即自动跳过 YouTube 广告。不会被 YouTube 广告拦截器警告检测到。
  31. // @description:zh-TW 立即自動跳過 YouTube 廣告。 YouTube 廣告攔截器警告未被偵測到。
  32. // @author tientq64
  33. // @icon https://cdn-icons-png.flaticon.com/64/2504/2504965.png
  34. // @match https://www.youtube.com/*
  35. // @match https://m.youtube.com/*
  36. // @match https://music.youtube.com/*
  37. // @exclude https://studio.youtube.com/*
  38. // @grant none
  39. // @license MIT
  40. // @compatible firefox
  41. // @compatible chrome
  42. // @compatible opera
  43. // @compatible safari
  44. // @compatible edge
  45. // @noframes
  46. // @homepage https://github.com/tientq64/userscripts/tree/main/scripts/Auto-Skip-YouTube-Ads
  47. // ==/UserScript==
  48.  
  49. function skipAd() {
  50. if (checkIsYouTubeShorts()) return
  51.  
  52. // This element appears when a video ad appears.
  53. const adShowing = document.querySelector('.ad-showing')
  54.  
  55. // Timed pie countdown ad.
  56. const pieCountdown = document.querySelector('.ytp-ad-timed-pie-countdown-container')
  57.  
  58. // Survey questions in video player.
  59. const surveyQuestions = document.querySelector('.ytp-ad-survey-questions')
  60.  
  61. if (adShowing === null && pieCountdown === null && surveyQuestions === null) return
  62.  
  63. const moviePlayerEl = document.querySelector('#movie_player')
  64. let playerEl
  65. let player
  66.  
  67. if (isYouTubeMobile || isYouTubeMusic) {
  68. playerEl = moviePlayerEl
  69. player = playerEl
  70. } else {
  71. playerEl = document.querySelector('#ytd-player')
  72. player = playerEl && playerEl.getPlayer()
  73. }
  74.  
  75. if (playerEl === null || player === null) {
  76. console.log({
  77. message: 'Player not found',
  78. timeStamp: getCurrentTimeString()
  79. })
  80. return
  81. }
  82.  
  83. // ad.classList.remove('ad-showing')
  84.  
  85. let adVideo = null
  86.  
  87. if (pieCountdown === null && surveyQuestions === null) {
  88. adVideo = document.querySelector(
  89. '#ytd-player video.html5-main-video, #song-video video.html5-main-video'
  90. )
  91.  
  92. console.table({
  93. message: 'Ad video',
  94. video: adVideo !== null,
  95. src: adVideo?.src,
  96. paused: adVideo?.paused,
  97. currentTime: adVideo?.currentTime,
  98. duration: adVideo?.duration,
  99. timeStamp: getCurrentTimeString()
  100. })
  101.  
  102. if (adVideo !== null) {
  103. adVideo.muted = true
  104. }
  105. if (adVideo === null || !adVideo.src || adVideo.paused || isNaN(adVideo.duration)) {
  106. return
  107. }
  108.  
  109. console.log({
  110. message: 'Ad video has finished loading',
  111. timeStamp: getCurrentTimeString()
  112. })
  113. }
  114.  
  115. if (isYouTubeMusic && adVideo !== null) {
  116. adVideo.currentTime = adVideo.duration
  117.  
  118. console.table({
  119. message: 'Ad skipped',
  120. timeStamp: getCurrentTimeString(),
  121. adShowing: adShowing !== null,
  122. pieCountdown: pieCountdown !== null,
  123. surveyQuestions: surveyQuestions !== null
  124. })
  125. } else {
  126. const videoData = player.getVideoData()
  127. const videoId = videoData.video_id
  128. const start = Math.floor(player.getCurrentTime())
  129.  
  130. if (moviePlayerEl !== null && moviePlayerEl.isSubtitlesOn()) {
  131. window.setTimeout(moviePlayerEl.toggleSubtitlesOn, 1000)
  132. }
  133.  
  134. if ('loadVideoWithPlayerVars' in playerEl) {
  135. playerEl.loadVideoWithPlayerVars({ videoId, start })
  136. } else {
  137. playerEl.loadVideoByPlayerVars({ videoId, start })
  138. }
  139.  
  140. console.table({
  141. message: 'Ad skipped',
  142. videoId,
  143. start,
  144. title: videoData.title,
  145. timeStamp: getCurrentTimeString(),
  146. adShowing: adShowing !== null,
  147. pieCountdown: pieCountdown !== null,
  148. surveyQuestions: surveyQuestions !== null
  149. })
  150. }
  151. }
  152.  
  153. function checkIsYouTubeShorts() {
  154. return location.pathname.startsWith('/shorts/')
  155. }
  156.  
  157. function getCurrentTimeString() {
  158. return new Date().toTimeString().split(' ', 1)[0]
  159. }
  160.  
  161. function addCss() {
  162. const adsSelectors = [
  163. // Ad banner in the upper right corner, above the video playlist.
  164. '#player-ads',
  165. '#panels > ytd-engagement-panel-section-list-renderer[target-id="engagement-panel-ads"]',
  166.  
  167. // Masthead ad on home page.
  168. '#masthead-ad',
  169.  
  170. // Sponsored ad video items on home page.
  171. // 'ytd-ad-slot-renderer',
  172.  
  173. // '.ytp-suggested-action',
  174. '.yt-mealbar-promo-renderer',
  175.  
  176. // Featured product ad banner at the bottom left of the video.
  177. '.ytp-featured-product',
  178.  
  179. // Products shelf ad banner below the video description.
  180. 'ytd-merch-shelf-renderer',
  181.  
  182. // YouTube Music Premium trial promotion dialog, bottom left corner.
  183. 'ytmusic-mealbar-promo-renderer',
  184.  
  185. // YouTube Music Premium trial promotion banner on home page.
  186. 'ytmusic-statement-banner-renderer'
  187. ]
  188. const adsSelector = adsSelectors.join(',')
  189. const css = `${adsSelector} { display: none !important; }`
  190. const style = document.createElement('style')
  191. style.textContent = css
  192. document.head.appendChild(style)
  193. }
  194.  
  195. /**
  196. * Remove ad elements using JavaScript because these selectors require the use of the CSS
  197. * `:has` selector which is not supported in older browser versions.
  198. */
  199. function removeAdElements() {
  200. const adSelectors = [
  201. // Sponsored ad video items on home page.
  202. // ['ytd-rich-item-renderer', '.ytd-ad-slot-renderer'],
  203.  
  204. // ['ytd-rich-section-renderer', '.ytd-statement-banner-renderer'],
  205.  
  206. // Ad videos on YouTube Shorts.
  207. ['ytd-reel-video-renderer', '.ytd-ad-slot-renderer']
  208.  
  209. // Ad blocker warning dialog.
  210. // ['tp-yt-paper-dialog', '#feedback.ytd-enforcement-message-view-model'],
  211.  
  212. // Survey dialog on home page, located at bottom right.
  213. // ['tp-yt-paper-dialog', ':scope > ytd-checkbox-survey-renderer'],
  214.  
  215. // Survey to rate suggested content, located at bottom right.
  216. // ['tp-yt-paper-dialog', ':scope > ytd-single-option-survey-renderer']
  217. ]
  218. for (const adSelector of adSelectors) {
  219. const adEl = document.querySelector(adSelector[0])
  220. if (adEl === null) continue
  221. const neededEl = adEl.querySelector(adSelector[1])
  222. if (neededEl === null) continue
  223. adEl.remove()
  224. }
  225. }
  226.  
  227. const isYouTubeMobile = location.hostname === 'm.youtube.com'
  228. const isYouTubeDesktop = !isYouTubeMobile
  229.  
  230. const isYouTubeMusic = location.hostname === 'music.youtube.com'
  231. const isYouTubeVideo = !isYouTubeMusic
  232.  
  233. addCss()
  234.  
  235. if (isYouTubeVideo) {
  236. window.setInterval(removeAdElements, 1000)
  237. removeAdElements()
  238. }
  239.  
  240. window.setInterval(skipAd, 500)
  241. skipAd()
  242.  
  243. // const observer = new MutationObserver(skipAd)
  244. // observer.observe(document.body, {
  245. // attributes: true,
  246. // attributeFilter: ['class'],
  247. // childList: true,
  248. // subtree: true
  249. // })

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址