YouTube去广告

这是一个去除YouTube广告的脚本,轻量且高效,它能丝滑的去除界面广告和视频广告,包括6s广告。

当前为 2023-05-04 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name YouTube去广告 YouTube AD Blocker
  3. // @name:zh-CN YouTube去广告
  4. // @name:zh-TW YouTube去廣告
  5. // @name:zh-HK YouTube去廣告
  6. // @name:zh-MO YouTube去廣告
  7. // @namespace http://tampermonkey.net/
  8. // @version 5.0
  9. // @description 这是一个去除YouTube广告的脚本,轻量且高效,它能丝滑的去除界面广告和视频广告,包括6s广告。This is a script that removes ads on YouTube, it's lightweight and efficient, capable of smoothly removing interface and video ads, including 6s ads.
  10. // @description:zh-CN 这是一个去除YouTube广告的脚本,轻量且高效,它能丝滑的去除界面广告和视频广告,包括6s广告。
  11. // @description:zh-TW 這是一個去除YouTube廣告的腳本,輕量且高效,它能絲滑地去除界面廣告和視頻廣告,包括6s廣告。
  12. // @description:zh-HK 這是一個去除YouTube廣告的腳本,輕量且高效,它能絲滑地去除界面廣告和視頻廣告,包括6s廣告。
  13. // @description:zh-MO 這是一個去除YouTube廣告的腳本,輕量且高效,它能絲滑地去除界面廣告和視頻廣告,包括6s廣告。
  14. // @author iamfugui
  15. // @match *://*.youtube.com/*
  16. // @icon https://www.google.com/s2/favicons?sz=64&domain=YouTube.com
  17. // @grant none
  18. // @license MIT
  19. // ==/UserScript==
  20. (function() {
  21. `use strict`;
  22.  
  23. //界面广告选择器
  24. const cssSeletorArr = [
  25. `#masthead-ad`,//首页顶部横幅广告.
  26. `ytd-rich-item-renderer.style-scope.ytd-rich-grid-row #content:has(.ytd-display-ad-renderer)`,//首页视频排版广告.
  27. `ytd-rich-section-renderer #dismissible`,//首页中部横幅广告.
  28. `.video-ads.ytp-ad-module`,//播放器底部广告.
  29. `tp-yt-paper-dialog:has(yt-mealbar-promo-renderer)`,//播放页会员促销广告.
  30. `#related #player-ads`,//播放页评论区右侧推广广告.
  31. `#related ytd-ad-slot-renderer`,//播放页评论区右侧视频排版广告.
  32. `ytd-ad-slot-renderer`,//搜索页广告.
  33. `yt-mealbar-promo-renderer`,//播放页会员推荐广告.
  34. ];
  35. const dev = false;//开发使用
  36. let video;//视频dom
  37.  
  38. /**
  39. * 将标准时间格式化
  40. * @param {Date} time 标准时间
  41. * @param {String} format 格式
  42. * @return {String}
  43. */
  44. function moment(time, format = `YYYY-MM-DD HH:mm:ss`) {
  45. // 获取年⽉⽇时分秒
  46. let y = time.getFullYear()
  47. let m = (time.getMonth() + 1).toString().padStart(2, `0`)
  48. let d = time.getDate().toString().padStart(2, `0`)
  49. let h = time.getHours().toString().padStart(2, `0`)
  50. let min = time.getMinutes().toString().padStart(2, `0`)
  51. let s = time.getSeconds().toString().padStart(2, `0`)
  52. if (format === `YYYY-MM-DD`) {
  53. return `${y}-${m}-${d}`
  54. } else {
  55. return `${y}-${m}-${d} ${h}:${min}:${s}`
  56. }
  57. }
  58.  
  59. /**
  60. * 输出信息
  61. * @param {String} msg 信息
  62. * @return {undefined}
  63. */
  64. function log(msg) {
  65. if(!dev){
  66. return false;
  67. }
  68. console.log(`${moment(new Date())} ${msg}`)
  69. }
  70.  
  71. /**
  72. * 获取当前url的参数,如果要查询特定参数请传参
  73. * @param {String} 要查询的参数
  74. * @return {String || Object}
  75. */
  76. function getUrlParams(param) {
  77. // 通过 ? 分割获取后面的参数字符串
  78. let urlStr = location.href.split(`?`)[1]
  79. if(!urlStr){
  80. return ``;
  81. }
  82. // 创建空对象存储参数
  83. let obj = {};
  84. // 再通过 & 将每一个参数单独分割出来
  85. let paramsArr = urlStr.split(`&`)
  86. for(let i = 0,len = paramsArr.length;i < len;i++){
  87. // 再通过 = 将每一个参数分割为 key:value 的形式
  88. let arr = paramsArr[i].split(`=`)
  89. obj[arr[0]] = arr[1];
  90. }
  91.  
  92. if(!param){
  93. return obj;
  94. }
  95.  
  96. return obj[param]||``;
  97. }
  98.  
  99. /**
  100. * 生成去除广告的css元素style并附加到HTML节点上
  101. * @param {String} styles 样式文本
  102. * @param {String} styleId 元素id
  103. * @return {undefined}
  104. */
  105. function generateRemoveADHTMLElement(styles,styleId) {
  106. //如果已经设置过,退出.
  107. if (document.getElementById(styleId)) {
  108. return false
  109. }
  110.  
  111. //设置移除广告样式.
  112. let style = document.createElement(`style`);//创建style元素.
  113. style.id = styleId;
  114. (document.querySelector(`head`) || document.querySelector(`body`)).appendChild(style);//将节点附加到HTML.
  115. style.appendChild(document.createTextNode(styles));//附加样式节点到元素节点.
  116. log(`屏蔽页面广告节点已生成`)
  117.  
  118. }
  119.  
  120. /**
  121. * 生成去除广告的css文本
  122. * @param {Array} cssSeletorArr 待设置css选择器数组
  123. * @return {String}
  124. */
  125. function generateRemoveADCssText(cssSeletorArr){
  126. cssSeletorArr.forEach((seletor,index)=>{
  127. cssSeletorArr[index]=`${seletor}{display:none!important}`;//遍历并设置样式.
  128. });
  129. return cssSeletorArr.join(` `);//拼接成字符串.
  130. }
  131.  
  132. /**
  133. * 去除播放中的广告
  134. * @return {undefined}
  135. */
  136. function removePlayerAD(){
  137. let observer;//监听器
  138.  
  139. //开始监听
  140. function startObserve(){
  141. video = document.querySelector(`video`);//获取视频节点
  142.  
  143. //广告节点监听
  144. const targetNode = document.querySelector(`.video-ads.ytp-ad-module`);
  145.  
  146. //这个视频不存在广告
  147. if(!targetNode){
  148. log(`这个视频不存在广告`);
  149. return false;
  150. }
  151.  
  152. // 监听视频中的广告并处理
  153. const config = {childList: true, subtree: true };// 监听目标节点本身与子树下节点的变动
  154. // 当观察到变动时执行的回调函数
  155. const callback = function (mutationsList, observer) {
  156. //拥有跳过按钮的广告.
  157. let skipButton = document.querySelector(`.ytp-ad-skip-button`);
  158. if(skipButton)
  159. {
  160. skipButton.click();// 跳过广告.
  161. log(`刚刚监听到了广告节点变化并使用按钮跳过了一条广告`);
  162. return false;//终止
  163. }
  164.  
  165. //没有跳过按钮的短广告.
  166. let shortAdMsg = document.querySelector(`.video-ads.ytp-ad-module .ytp-ad-player-overlay`);
  167. if(shortAdMsg){
  168. log(`刚刚监听到了广告节点变化并即将跳过一条广告`);
  169. video.currentTime = 1024;
  170. return false;//终止
  171. }
  172.  
  173. log(`刚刚监听到了广告节点变化但都没有处理:`);
  174.  
  175. }
  176. observer = new MutationObserver(callback);// 创建一个观察器实例并传入回调函数
  177. observer.observe(targetNode, config);// 以上述配置开始观察广告节点
  178. }
  179.  
  180. //结束监听
  181. function closeObserve(){
  182. observer.disconnect();
  183. observer = null;
  184. }
  185.  
  186. //轮询任务
  187. setInterval(function(){
  188. //视频播放页
  189. if(getUrlParams(`v`)){
  190. if(observer){
  191. return false;
  192. }
  193. startObserve();
  194. }else{
  195. //其它界面
  196. if(!observer){
  197. return false;
  198. }
  199. closeObserve();
  200. }
  201. },16.6);
  202.  
  203. log(`去除视频广告脚本持续运行中`)
  204. }
  205.  
  206. /**
  207. * main函数
  208. */
  209. function main(){
  210. generateRemoveADHTMLElement(generateRemoveADCssText(cssSeletorArr),`removeAD`);//移除界面中的广告.
  211. removePlayerAD();//移除播放中的广告.
  212. }
  213.  
  214. if (document.readyState === `loading`) {
  215. log(`YouTube去广告脚本即将调用:`);
  216. document.addEventListener(`DOMContentLoaded`, main);// 此时加载尚未完成
  217. } else {
  218. log(`YouTube去广告脚本快速调用:`);
  219. main();// 此时`DOMContentLoaded` 已经被触发
  220. }
  221.  
  222. })();

QingJ © 2025

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