YouTube去广告

这个脚本可以移除所有广告,包括所有视频广告.简单高效的YouTube去广告脚本,拒绝花里胡哨.你可以尝试为常量cssSeletorArr定义元素.

目前为 2023-04-21 提交的版本。查看 最新版本

  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. // @name:ar YouTube AD Blocker
  8. // @name:bg YouTube AD Blocker
  9. // @name:cs YouTube AD Blocker
  10. // @name:da YouTube AD Blocker
  11. // @name:de YouTube AD Blocker
  12. // @name:el YouTube AD Blocker
  13. // @name:eo YouTube AD Blocker
  14. // @name:es YouTube AD Blocker
  15. // @name:fi YouTube AD Blocker
  16. // @name:fr YouTube AD Blocker
  17. // @name:fr-CA YouTube AD Blocker
  18. // @name:he YouTube AD Blocker
  19. // @name:hu YouTube AD Blocker
  20. // @name:id YouTube AD Blocker
  21. // @name:nb YouTube AD Blocker
  22. // @name:nl YouTube AD Blocker
  23. // @name:pl YouTube AD Blocker
  24. // @name:pt-BR YouTube AD Blocker
  25. // @name:ro YouTube AD Blocker
  26. // @name:ru YouTube AD Blocker
  27. // @name:sk YouTube AD Blocker
  28. // @name:sr YouTube AD Blocker
  29. // @name:sv YouTube AD Blocker
  30. // @name:th YouTube AD Blocker
  31. // @name:tr YouTube AD Blocker
  32. // @name:uk YouTube AD Blocker
  33. // @name:ug YouTube AD Blocker
  34. // @name:vi YouTube AD Blocker
  35. // @name:it YouTube AD Blocker
  36. // @name:ja YouTubeの広告を削除します
  37. // @name:kr 포함한 YouTube 광고 차단
  38. // @name:ko 포함한 YouTube 광고 차단
  39.  
  40. // @namespace http://tampermonkey.net/
  41. // @version 1.70
  42.  
  43. // @description 这个脚本可以移除所有广告,包括所有视频广告.简单高效的YouTube去广告脚本,拒绝花里胡哨.你可以尝试为常量cssSeletorArr定义元素.This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  44. // @description:zh-CN 这个脚本可以移除所有广告,包括所有视频广告.简单高效的YouTube去广告脚本,拒绝花里胡哨.你可以尝试为常量cssSeletorArr定义元素.
  45. // @description:zh-TW 這個腳本可以移除所有廣告,包括所有視頻廣告.簡單高效的YouTube去廣告腳本,拒絕花裏胡哨.你可以嘗試為常量cssSeletorArr定義元素.
  46. // @description:zh-HK 這個腳本可以移除所有廣告,包括所有視頻廣告.簡單高效的YouTube去廣告腳本,拒絕花裏胡哨.你可以嘗試為常量cssSeletorArr定義元素.
  47. // @description:zh-MO 這個腳本可以移除所有廣告,包括所有視頻廣告.簡單高效的YouTube去廣告腳本,拒絕花裏胡哨.你可以嘗試為常量cssSeletorArr定義元素.
  48. // @description:ar This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  49. // @description:bg This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  50. // @description:cs This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  51. // @description:da This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  52. // @description:de This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  53. // @description:el This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  54. // @description:eo This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  55. // @description:es This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  56. // @description:fi This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  57. // @description:fr This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  58. // @description:fr-CA This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  59. // @description:he This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  60. // @description:hu This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  61. // @description:id This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  62. // @description:nb This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  63. // @description:nl This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  64. // @description:pl This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  65. // @description:pt-BR This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  66. // @description:ro This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  67. // @description:ru This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  68. // @description:sk This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  69. // @description:sr This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  70. // @description:sv This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  71. // @description:th This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  72. // @description:tr This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  73. // @description:uk This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  74. // @description:ug This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  75. // @description:vi This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  76. // @description:it This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  77. // @description:ja This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  78. // @description:kr This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  79. // @description:ko This script can remove all ads, including all video ads. It is a simple and efficient YouTube ad-blocking script that rejects fancy gimmicks. You can try defining elements for the constant cssSelectorArr.
  80.  
  81.  
  82. // @author iamfugui
  83. // @match *://*.youtube.com/*
  84. // @icon https://www.google.com/s2/favicons?sz=64&domain=YouTube.com
  85. // @grant none
  86. // @license MIT
  87. // ==/UserScript==
  88. (function() {
  89. `use strict`;
  90.  
  91. //界面广告选择器
  92. const cssSeletorArr = [
  93. `#masthead-ad`,//首页顶部横幅广告. On the homepage ad.
  94. `ytd-rich-item-renderer.style-scope.ytd-rich-grid-row #content:has(.ytd-display-ad-renderer)`,//首页视频排版广告. On the homepage ad.
  95. `ytd-rich-section-renderer #dismissible`,//首页中部横幅广告. On the homepage ad.
  96. `.video-ads.ytp-ad-module`,//播放器底部广告. On-video ad.
  97. `tp-yt-paper-dialog:has(yt-mealbar-promo-renderer)`,//播放页会员促销广告.On-video ad.
  98. `#related #player-ads`,//播放页评论区右侧推广广告. On-video ad.
  99. `#related ytd-ad-slot-renderer`,//播放页评论区右侧视频排版广告. On-video ad.
  100. `ytd-ad-slot-renderer`,//搜索页广告. Search results page ad.
  101. `yt-mealbar-promo-renderer`,//播放页会员推荐广告 On-video ad.
  102. ];
  103.  
  104. const dev = true;//开发用
  105.  
  106. let lastTime = parseInt(getUrlParams(`t`))||0;//由于youtube出现广告前是先将进度条归零再进行广告node的更新,故此将上一次进度记录
  107. let currentTime = parseInt(getUrlParams(`t`))||0;//根据url初始化当前播放时间s
  108. let videoLink = `${location.href.split(`&`)[0]}`;//当前视频链接
  109. let video;
  110.  
  111.  
  112. /**
  113. * 将标准时间格式化
  114. * @param {Date} time 标准时间
  115. * @param {String} format 格式
  116. * @return {String}
  117. */
  118. function moment(time, format = `YYYY-MM-DD HH:mm:ss`) {
  119. // 获取年⽉⽇时分秒
  120. let y = time.getFullYear()
  121. let m = (time.getMonth() + 1).toString().padStart(2, `0`)
  122. let d = time.getDate().toString().padStart(2, `0`)
  123. let h = time.getHours().toString().padStart(2, `0`)
  124. let min = time.getMinutes().toString().padStart(2, `0`)
  125. let s = time.getSeconds().toString().padStart(2, `0`)
  126. if (format === `YYYY-MM-DD`) {
  127. return `${y}-${m}-${d}`
  128. } else {
  129. return `${y}-${m}-${d} ${h}:${min}:${s}`
  130. }
  131. }
  132.  
  133.  
  134. /**
  135. * 输出信息
  136. * @param {String} msg 信息
  137. * @return {undefined}
  138. */
  139. function log(msg) {
  140. if(!dev){
  141. return false;
  142. }
  143. console.log(`${moment(new Date())} ${msg}`)
  144. }
  145.  
  146. /**
  147. * 获取当前url的参数,如果要查询特定参数请传参
  148. * @param {String} 要查询的参数
  149. * @return {String || Object}
  150. */
  151. function getUrlParams(param) {
  152. // 通过 ? 分割获取后面的参数字符串
  153. let urlStr = location.href.split(`?`)[1]
  154. if(!urlStr){
  155. return ``;
  156. }
  157. // 创建空对象存储参数
  158. let obj = {};
  159. // 再通过 & 将每一个参数单独分割出来
  160. let paramsArr = urlStr.split(`&`)
  161. for(let i = 0,len = paramsArr.length;i < len;i++){
  162. // 再通过 = 将每一个参数分割为 key:value 的形式
  163. let arr = paramsArr[i].split(`=`)
  164. obj[arr[0]] = arr[1];
  165. }
  166.  
  167. if(!param){
  168. return obj;
  169. }
  170.  
  171. return obj[param]||``;
  172. }
  173.  
  174. /**
  175. * 得到跳过链接
  176. * @return {String}
  177. */
  178. function getSkipAdUrl(){
  179. let urlParams = getUrlParams();
  180. let url = `${videoLink}`;
  181. for(let key in urlParams){
  182. if(key !== `v` && key !== `t`){
  183. url = `${url}&${key}=${urlParams[key]}`
  184. }
  185. }
  186. return `${url}&t=${parseInt(lastTime)}s`;
  187. }
  188.  
  189. /**
  190. * 生成去除广告的css元素style并附加到HTML节点上
  191. * @param {String} styles 样式文本
  192. * @param {String} styleId 元素id
  193. * @return {undefined}
  194. */
  195. function generateRemoveADHTMLElement(styles,styleId) {
  196. //如果已经设置过,退出.
  197. if (document.getElementById(styleId)) {
  198. return false
  199. }
  200.  
  201. //设置移除广告样式.
  202. let style = document.createElement(`style`);//创建style元素.
  203. style.id = styleId;
  204. (document.querySelector(`head`) || document.querySelector(`body`)).appendChild(style);//将节点附加到HTML.
  205. style.appendChild(document.createTextNode(styles));//附加样式节点到元素节点.
  206. log(`屏蔽页面广告节点已生成`)
  207.  
  208. }
  209.  
  210. /**
  211. * 生成去除广告的css文本
  212. * @param {Array} cssSeletorArr 待设置css选择器数组
  213. * @return {String}
  214. */
  215. function generateRemoveADCssText(cssSeletorArr){
  216. cssSeletorArr.forEach((seletor,index)=>{
  217. cssSeletorArr[index]=`${seletor}{display:none!important}`;//遍历并设置样式.
  218. });
  219. return cssSeletorArr.join(` `);//拼接成字符串.
  220. }
  221.  
  222.  
  223. /**
  224. * 检测用户切换了视频
  225. * @return {undefined}
  226. */
  227. function switchVideoHook(){
  228. if(videoLink !== `${location.href.split(`&`)[0]}`){
  229. videoLink = location.href.split(`&`)[0];//更新链接
  230. lastTime = parseInt(getUrlParams(`t`))||0;//根据url初始化当前播放时间s
  231. currentTime = parseInt(getUrlParams(`t`))||0;//根据url初始化当前播放时间s
  232. log(`检测到用户切换了视频,已更新播放进度`)
  233. }
  234. }
  235.  
  236. /**
  237. * 去除播放中的广告
  238. * @return {undefined}
  239. */
  240. function removePlayerAD(){
  241. let observer;//监听器
  242. let progress;//进度条node
  243. let updateTimerId;//信息更新定时器
  244.  
  245. //点击进度条监听
  246. let clickProgressHandler = function(){
  247. video = document.querySelector(`video`);
  248. lastTime = video.currentTime;//记录播放进度
  249. currentTime = video.currentTime;//记录播放进度
  250.  
  251. log(`进度条监听`);
  252. log(lastTime);
  253. }
  254.  
  255. //开始监听
  256. function startObserve(){
  257. //广告节点监听
  258. const targetNode = document.querySelector(`.video-ads.ytp-ad-module`);
  259.  
  260. //这个视频未存在广告
  261. if(!targetNode){
  262. return false;
  263. }
  264.  
  265. const config = {childList: true, subtree: true };// 监听目标节点本身与子树下节点的变动
  266. // 当观察到变动时执行的回调函数
  267. const callback = function (mutationsList, observer) {
  268. switchVideoHook();//检测用户是否切换了视频
  269.  
  270. //拥有跳过按钮的广告.
  271. let skipButton = document.querySelector(`.ytp-ad-skip-button`);
  272. if(skipButton)
  273. {
  274. skipButton.click();// 跳过广告.
  275. log(`使用按钮跳过了一条广告`);
  276. return false;//终止
  277. }
  278.  
  279. //没有跳过按钮的短广告.
  280. let shortAdMsg = document.querySelector(`.video-ads.ytp-ad-module .ytp-ad-player-overlay`);
  281. if(shortAdMsg){
  282. log(`查看上一次进度${lastTime}`);
  283. log(`查看当前进度${currentTime}`);
  284. video.pause();//暂停播放避免继续请求资源
  285. location.replace(getSkipAdUrl());//得到跳转的url,重新加载.
  286. closeObserve();
  287. return false;//终止
  288. }
  289.  
  290. log(`刚刚监听到了节点变化但都没有处理:`);
  291. log(skipButton);
  292. log(shortAdMsg);
  293.  
  294. }
  295. // 创建一个观察器实例并传入回调函数
  296. observer = new MutationObserver(callback);
  297. // 以上述配置开始观察广告节点
  298. observer.observe(targetNode, config);
  299.  
  300. //定时更新信息
  301. updateTimerId =setInterval(function(){
  302. switchVideoHook();//检测用户是否切换了视频
  303.  
  304. //如果不是播放页就退出,因为youtube跳转页面时并不会reload页面,所以继续执行定时器,
  305. video = document.querySelector(`video`);
  306. if(!video){
  307. return false;
  308. }
  309. videoLink = location.href.split(`&`)[0];//更新链接
  310. lastTime = currentTime;
  311. currentTime = video.currentTime;//未检测到广告,记录播放进度
  312.  
  313. log(`记录当前进度:`)
  314. log(currentTime)
  315. },2000);//太快,进度条归零但广告节点却没有出来会判断错误
  316.  
  317. //监听点击进度条,主要是避免定时器对视频进度监听太慢导致进度条在跳转广告后出现偏移的情况
  318. progress = document.querySelector(`.ytp-progress-bar-container`);
  319. progress.addEventListener(`click`,clickProgressHandler);
  320.  
  321. }
  322.  
  323. //结束监听
  324. function closeObserve(){
  325. observer.disconnect();
  326. clearInterval(updateTimerId);
  327. progress.removeEventListener(`click`,clickProgressHandler);
  328. observer = null;
  329. updateTimerId = null;
  330. progress = null;
  331. }
  332.  
  333.  
  334. setInterval(function(){
  335. //视频播放页
  336. if(getUrlParams(`v`)){
  337. if(observer && updateTimerId && progress){
  338. return false;
  339. }
  340. startObserve();
  341. }else{
  342. //其它界面
  343. if(!observer && !updateTimerId && !progress){
  344. return false;
  345. }
  346. closeObserve();
  347. }
  348. },16.7);
  349.  
  350. log(`去除视频广告脚本持续运行中`)
  351. }
  352.  
  353. /**
  354. * main函数
  355. */
  356. function main(){
  357. generateRemoveADHTMLElement(generateRemoveADCssText(cssSeletorArr),`removeAD`);//移除界面中的广告.
  358. removePlayerAD();//移除播放中的广告.
  359. }
  360.  
  361. if (document.readyState === `loading`) {
  362. log(`YouTube去广告脚本即将调用:`);
  363. document.addEventListener(`DOMContentLoaded`, main);// 此时加载尚未完成
  364. } else {
  365. log(`YouTube去广告脚本快速调用:`);
  366. main();// 此时`DOMContentLoaded` 已经被触发
  367. }
  368.  
  369. })();