您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Blocks various YouTube ads, and Home page banners with fucking Sponsored Video Ads.
// ==UserScript== // @name Enhanced YouTube Ad Blocker // @namespace http://tampermonkey.net/ // @version 1.2.1 // @license MIT // @description Blocks various YouTube ads, and Home page banners with fucking Sponsored Video Ads. // @author vippium // @match https://www.youtube.com/* // @grant none // @run-at document-start // @require https://cdn.jsdelivr.net/gh/cyfung1031/userscript-supports@8fac46500c5a916e6ed21149f6c25f8d1c56a6a3/library/ytZara.js // ==/UserScript== (function () { 'use strict'; // 1. Remove rich grid ad slots on homepage const wm = new WeakSet(); const removeAdsSlot = async (grid) => { const td = grid.data; if (td && !wm.has(td)) { const md = Object.assign({}, td); md.contents = md.contents.filter(content => { let isadSlotRenderer = ((((content || 0).richItemRenderer || 0).content || 0).adSlotRenderer || null) !== null; return !isadSlotRenderer; }); wm.add(md); grid.data = md; } }; ytZara.ytProtoAsync("ytd-rich-grid-renderer").then(proto => { proto.dataChanged = ((orig) => function () { removeAdsSlot(this); return orig.apply(this, arguments); })(proto.dataChanged); }); // 2. Observe and remove banner ads, masthead ads const adSelectors = [ 'ytd-banner-promo-renderer', 'ytd-mealbar-promo-renderer', 'ytd-display-ad-renderer', '#player-ads', '.ytp-ad-module', '.ytp-ad-overlay-container', 'ytd-companion-slot-renderer', '.video-ads', 'div[class*="ytd-in-feed"] ytd-ad-slot-renderer', 'ytd-promoted-sparkles-web-renderer', 'ytd-search-pyv-renderer', '.ytp-ad-skip-button-container', '.ytp-ad-player-overlay' ]; const removeAdElements = () => { adSelectors.forEach(selector => { document.querySelectorAll(selector).forEach(el => el.remove()); }); }; const adObserver = new MutationObserver(() => { removeAdElements(); }); const initAdObserver = () => { removeAdElements(); if (document.body) { adObserver.observe(document.body, { childList: true, subtree: true }); } else { // If document.body is not available yet, set up an interval to check const checkBody = setInterval(() => { if (document.body) { adObserver.observe(document.body, { childList: true, subtree: true }); clearInterval(checkBody); // Stop checking once it's available } }, 100); // Check every 100ms } }; document.addEventListener('DOMContentLoaded', initAdObserver); // 3. Block in-video ad playback by overriding player response const overridePlayerAds = () => { const originalDefineProperty = Object.defineProperty; Object.defineProperty = function(obj, prop, descriptor) { if (prop === 'playerResponse' && descriptor && descriptor.set) { const originalSetter = descriptor.set; descriptor.set = function(response) { if (response && response.adPlacements) { delete response.adPlacements; } originalSetter.call(this, response); }; } return originalDefineProperty.call(Object, obj, prop, descriptor); }; }; overridePlayerAds(); // 4. SponsorBlock API integration: Skip sponsor segments in videos const sponsorBlockApiUrl = 'https://sponsor.ajay.app/api/skipSegments'; let videoId = null; const fetchSponsorSegments = (videoId) => { fetch(`${sponsorBlockApiUrl}?videoId=${videoId}`) .then(response => response.json()) .then(data => { if (data && data.segments) { skipSponsorSegments(data.segments); } }) .catch(error => { console.error('Error fetching SponsorBlock data:', error); }); }; const skipSponsorSegments = (segments) => { const player = document.querySelector('video'); if (!player) return; const currentTime = player.currentTime; segments.forEach(segment => { if (currentTime >= segment.start && currentTime <= segment.end) { player.currentTime = segment.end; // Skip to the end of the sponsor segment } }); }; // 5. Monitor for video changes to grab the videoId and use SponsorBlock API const videoObserver = new MutationObserver(() => { const videoElement = document.querySelector('video'); if (videoElement && videoElement.src && videoElement.src.includes('youtube.com/watch?v=')) { const videoUrlParams = new URLSearchParams(window.location.search); videoId = videoUrlParams.get('v'); if (videoId) { fetchSponsorSegments(videoId); } } }); videoObserver.observe(document.body, { childList: true, subtree: true }); // 6. Restore the Dislike button (like in older versions of YouTube) const restoreDislikeButton = () => { const dislikeButton = document.querySelector('.ytd-toggle-button-renderer.style-scope.ytd-video-primary-info-renderer'); const dislikeButtonText = dislikeButton && dislikeButton.querySelector('#text'); if (dislikeButtonText) { dislikeButtonText.style.display = 'inline'; // Make the dislike count visible } }; // Monitor for dislike button visibility on the video page const dislikeObserver = new MutationObserver(() => { restoreDislikeButton(); }); dislikeObserver.observe(document.body, { childList: true, subtree: true }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址