您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
跳过广告、过滤字幕、黑屏提示、AI自愈、本地缓存、自动识别广告拦截警告并重新加载、支持首页广告屏蔽!完全本地运行、无设置面板。优化:改进AI响应解析、异步处理、性能优化、错误处理增强、代码结构化。
// ==UserScript== // @name YouTube AI广告稳定自愈版 v2.0.0 (优化更新版) // @namespace http://tampermonkey.net/ // @version 2.0.0 // @description 跳过广告、过滤字幕、黑屏提示、AI自愈、本地缓存、自动识别广告拦截警告并重新加载、支持首页广告屏蔽!完全本地运行、无设置面板。优化:改进AI响应解析、异步处理、性能优化、错误处理增强、代码结构化。 // @author little fool (optimized by Grok) // @match *://www.youtube.com/* // @match *://m.youtube.com/* // @match *://music.youtube.com/* // @match *://www.youtube-nocookie.com/* // @grant GM_xmlhttpRequest // @grant GM_getValue // @grant GM_setValue // @connect openkey.cloud // @run-at document-end // ==/UserScript== (function () { 'use strict'; const API_URL = 'https://openkey.cloud/v1/chat/completions'; const API_KEY = ['sk-', '1ytLN', 'fSpk5R34n', 'jTF628665', '6331c426cAeCb95E266F8D377'].join(''); const CACHE_KEY = 'yt_ad_selectors_cache'; const HISTORY_KEY = 'yt_ad_selectors_history'; const UPDATE_KEY = 'yt_ad_last_update'; const BASE_SELECTORS = new Set([ '.ytp-ad-module', '.ytp-ad-overlay-container', '.ytp-ad-player-overlay', '.ad-showing .video-ads', '#player-ads' ]); let dynamicSelectors = new Set(); let lastUpdate = 0; let previousMuted = null; let wasAdPlaying = false; let refreshAttempts = 0; const MAX_REFRESH_ATTEMPTS = 5; const REFRESH_INTERVAL = 5000; const UPDATE_INTERVAL = 3600000; // 1 hour const log = (...args) => console.log('[YT净化 v2.0.0]', ...args); function getVideo() { return document.querySelector('video') || document.querySelector('ytd-player video') || document.querySelector('#movie_player video'); } function isVideoPage() { return location.pathname.startsWith('/watch') || location.pathname.startsWith('/tv') || location.pathname.startsWith('/embed'); } function isHomePage() { return location.pathname === '/'; } async function updateSelectorsViaAI() { if (Date.now() - lastUpdate < UPDATE_INTERVAL) return; try { const response = await new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: 'POST', url: API_URL, headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${API_KEY}` }, data: JSON.stringify({ model: 'gpt-4o', messages: [{ role: 'user', content: "请提供当前YouTube最新广告CSS选择器数组,仅返回JSON格式的数组,如 ['.ytp-ad-module', ...]。确保选择器准确且最新。" }], temperature: 0.3 }), onload: resolve, onerror: reject }); }); const reply = JSON.parse(response.responseText); let content = reply.choices[0].message.content.trim().replace(/```json|```/g, ''); const selectors = JSON.parse(content); if (Array.isArray(selectors) && selectors.length > 0) { dynamicSelectors = new Set(selectors); GM_setValue(CACHE_KEY, Array.from(dynamicSelectors)); GM_setValue(UPDATE_KEY, Date.now()); lastUpdate = Date.now(); let history = GM_getValue(HISTORY_KEY, []); history.unshift(Array.from(dynamicSelectors)); if (history.length > 10) history = history.slice(0, 10); GM_setValue(HISTORY_KEY, history); log('[AI更新成功]', Array.from(dynamicSelectors)); } else { log('[AI格式错误]', content); fallbackSelectors(); } } catch (e) { log('[AI请求/解析失败]', e); fallbackSelectors(); } } function fallbackSelectors() { const history = GM_getValue(HISTORY_KEY, []); if (history.length > 0) { dynamicSelectors = new Set(history[0]); log('[容灾] 使用历史缓存', Array.from(dynamicSelectors)); } else { dynamicSelectors = new Set(); log('[严重容灾] 无历史,仅用默认选择器'); } } function hideAds() { const allSelectors = new Set([...BASE_SELECTORS, ...dynamicSelectors]); allSelectors.forEach(sel => { document.querySelectorAll(sel).forEach(el => { if (el.style.opacity !== '0.01') { Object.assign(el.style, { opacity: '0.01', pointerEvents: 'none', position: 'absolute', left: '-9999px', top: '-9999px', zIndex: '0' }); } }); }); } function clickSkipButton() { const btn = document.querySelector('.ytp-ad-skip-button'); if (btn && btn.offsetParent !== null) { setTimeout(() => btn.click(), 300 + Math.random() * 300); } } function accelerateAdPlayback() { const video = getVideo(); if (!video) return; const ad = document.querySelector('.ad-showing'); if (ad) { if (video.playbackRate !== 16) video.playbackRate = 16; if (!wasAdPlaying) { previousMuted = video.muted; video.muted = true; log('[广告中] 倍速+静音'); } } else { if (video.playbackRate !== 1) video.playbackRate = 1; if (wasAdPlaying && previousMuted !== null) { video.muted = previousMuted; previousMuted = null; log('[广告结束] 恢复音量'); } } wasAdPlaying = !!ad; if (!ad) refreshAttempts = 0; } function removeAdSubtitles() { const keywords = ['广告', '贊助', '推广', 'Sponsored', 'Sponsor']; document.querySelectorAll('.ytp-caption-segment').forEach(el => { if (keywords.some(k => el.textContent.includes(k)) && el.style.display !== 'none') { el.style.display = 'none'; el.textContent = ''; } }); } function detectAdBlackScreen() { const video = getVideo(); const isAd = document.querySelector('.ad-showing'); const isBlack = video && video.readyState >= 2 && video.videoWidth === 0; const stuck = isAd && video?.currentTime < 2; if ((isAd && isBlack) || stuck) { showTip('yt-ad-wait-tip', '⏳ 正在跳过广告,请稍候...'); } else { removeTip('yt-ad-wait-tip'); } } function detectAdBlockWarning() { const signs = [ '您似乎在使用广告拦截器', '广告支持我们的服务', '关闭广告拦截', 'Ad blockers violate YouTube’s Terms', '广告拦截影响观看体验', '使用广告拦截器违反 YouTube 服务条款' ]; return signs.some(k => document.body.innerText.includes(k)); } function showTip(id, message) { let tip = document.getElementById(id); if (!tip) { tip = document.createElement('div'); tip.id = id; Object.assign(tip.style, { position: 'fixed', top: id.includes('wait') ? '20px' : '60px', left: '50%', transform: 'translateX(-50%)', backgroundColor: id.includes('wait') ? '#111' : '#c00', color: '#fff', padding: '10px 16px', borderRadius: '8px', zIndex: '9999', fontSize: '14px', fontWeight: 'bold', boxShadow: '0 2px 8px rgba(0,0,0,0.3)', opacity: '0.95' }); document.body.appendChild(tip); } if (tip.innerText !== message) tip.innerText = message; } function removeTip(id) { const el = document.getElementById(id); if (el) el.remove(); } function hideHomepageAds() { const keywords = ['广告', '推广', 'Sponsored', '赞助']; document.querySelectorAll('ytd-rich-item-renderer, ytd-video-renderer').forEach(item => { const text = item.innerText; if (keywords.some(k => text.includes(k)) && item.style.display !== 'none') { item.style.display = 'none'; } }); } function observeAdElements() { const observer = new MutationObserver(() => { hideAds(); clickSkipButton(); accelerateAdPlayback(); removeAdSubtitles(); }); observer.observe(document.body, { childList: true, subtree: true }); } async function init() { const cached = GM_getValue(CACHE_KEY, []); dynamicSelectors = new Set(cached); lastUpdate = GM_getValue(UPDATE_KEY, 0); await updateSelectorsViaAI(); setInterval(updateSelectorsViaAI, UPDATE_INTERVAL); if (isVideoPage()) { observeAdElements(); setInterval(detectAdBlackScreen, 1000); setInterval(() => { if (detectAdBlockWarning()) { if (refreshAttempts < MAX_REFRESH_ATTEMPTS) { refreshAttempts++; showTip('yt-adblock-refresh-tip', `⚠️ 检测到广告拦截器提示,正在重新加载页面(第 ${refreshAttempts} 次)`); setTimeout(() => location.href = location.href, 800); } else { removeTip('yt-adblock-refresh-tip'); } } else { removeTip('yt-adblock-refresh-tip'); } }, REFRESH_INTERVAL); } if (isHomePage()) { setInterval(hideHomepageAds, 2000); } } init(); })();