YouTube AI广告助手 (调试版)

AI动态更新选择器 + 自动静音加速广告 + 自动跳过广告按钮 + 首页广告隐藏 + 调试面板实时状态显示

// ==UserScript==
// @name         YouTube AI广告助手 (调试版)
// @namespace    http://tampermonkey.net/
// @version      2.0
// @description  AI动态更新选择器 + 自动静音加速广告 + 自动跳过广告按钮 + 首页广告隐藏 + 调试面板实时状态显示
// @author       Little Fool
// @match        *://www.youtube.com/*
// @match        *://m.youtube.com/*
// @match        *://music.youtube.com/*
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_xmlhttpRequest
// @run-at       document-end
// ==/UserScript==

(function () {
  'use strict';

  // =============================
  //  1. API 管理
  // =============================
  const API_URL = 'https://openkey.cloud/v1/chat/completions';

  function getApiKey() {
    return GM_getValue("YT_AI_API_KEY", null);
  }

  // =============================
  //  2. 日志
  // =============================
  const log = (...args) => console.log("[YT广告助手]", ...args);

  // =============================
  //  3. 广告规则
  // =============================
  const LOCAL_RULES = [
    '.ytp-ad-module', '.ytp-ad-overlay-container', '.ytp-ad-player-overlay',
    '#player-ads', '.ad-showing .video-ads', 'ytd-ad-slot-renderer',
    'ytd-display-ad-renderer', 'ytd-in-feed-ad-layout-renderer',
    'ytd-action-companion-ad-renderer', 'ytd-promoted-video-renderer',
    '#masthead-ad', 'ytd-banner-promo-renderer', 'ytd-rich-item-renderer[is-ad]',
  ];

  let selectors = new Set(LOCAL_RULES);

  // =============================
  //  4. AI 更新选择器
  // =============================
  async function fetchAdSelectorsFromAI() {
    const API_KEY = getApiKey();
    if (!API_KEY) {
      log("⚠️ 未设置 API KEY,请运行 GM_setValue('YT_AI_API_KEY','你的key')");
      return;
    }

    try {
      const res = 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-mini',
            messages: [
              { role: 'user', content: "请提供最新的YouTube广告CSS选择器数组,仅返回JSON数组" }
            ],
            temperature: 0.2
          }),
          onload: resolve,
          onerror: reject
        });
      });

      const result = JSON.parse(res.responseText);
      const selectorsText = result?.choices?.[0]?.message?.content?.trim();
      const newSelectors = JSON.parse(selectorsText);

      if (Array.isArray(newSelectors) && newSelectors.length > 0) {
        selectors = new Set([...LOCAL_RULES, ...newSelectors]);
        GM_setValue("yt_ad_selectors", Array.from(selectors));
        log("✅ AI 更新选择器成功", selectors.size);
      }
    } catch (err) {
      log("⚠️ AI 更新失败,使用缓存/本地规则", err);
      loadLocalSelectors();
    }
  }

  function loadLocalSelectors() {
    const cached = GM_getValue("yt_ad_selectors", []);
    if (Array.isArray(cached) && cached.length > 0) {
      selectors = new Set(cached);
      log("📥 使用缓存选择器", selectors.size);
    } else {
      selectors = new Set(LOCAL_RULES);
      GM_setValue("yt_ad_selectors", LOCAL_RULES);
      log("📥 使用本地默认规则");
    }
  }

  // =============================
  //  5. 调试面板
  // =============================
  function createDebugPanel() {
    const panel = document.createElement('div');
    panel.id = 'yt-ad-debug-panel';
    panel.style.cssText = `
      position: fixed;
      bottom: 80px;
      right: 20px;
      width: 280px;
      max-height: 300px;
      overflow-y: auto;
      background: rgba(0,0,0,0.8);
      color: #0f0;
      font-size: 12px;
      line-height: 1.4;
      padding: 10px;
      border-radius: 8px;
      z-index: 999999;
      display: none;
    `;
    document.body.appendChild(panel);

    // 浮动按钮
    const toggleBtn = document.createElement('button');
    toggleBtn.innerText = '调试';
    toggleBtn.style.cssText = `
      position: fixed;
      bottom: 20px;
      right: 20px;
      width: 60px;
      height: 40px;
      border-radius: 8px;
      border: none;
      background: #ff5722;
      color: #fff;
      font-size: 14px;
      cursor: pointer;
      z-index: 999999;
    `;
    document.body.appendChild(toggleBtn);

    toggleBtn.addEventListener('click', () => {
      panel.style.display = panel.style.display === 'none' ? 'block' : 'none';
    });

    return panel;
  }

  const debugPanel = createDebugPanel();

  function updateDebugPanel(info) {
    if (!debugPanel) return;
    debugPanel.innerHTML = `
      <div><b>🎯 YouTube 广告调试面板</b></div>
      <div>检测到广告元素: ${info.ads.length}</div>
      <div>最新广告选择器: ${info.lastSelector || '无'}</div>
      <div>是否加速: ${info.accelerated ? '✅ 已加速' : '❌ 未加速'}</div>
      <div>是否点击跳过: ${info.skipped ? '✅ 已跳过' : '❌ 无按钮'}</div>
    `;
  }

  // =============================
  //  6. 广告处理逻辑
  // =============================
  function getVideo() {
    return document.querySelector("video");
  }

  function hideAds() {
    let detected = [];
    selectors.forEach(sel => {
      document.querySelectorAll(sel).forEach(el => {
        el.style.display = 'none';
        el.style.opacity = '0.01';
        el.style.pointerEvents = 'none';
        detected.push(sel);
      });
    });
    updateDebugPanel({
      ads: detected,
      lastSelector: detected[0] || null,
      accelerated: false,
      skipped: false
    });
  }

  function clickSkip() {
    const btn = document.querySelector('.ytp-ad-skip-button');
    let skipped = false;
    if (btn && btn.offsetParent !== null) {
      btn.click();
      skipped = true;
      log("⏭️ 自动跳过广告");
    }
    updateDebugPanel({
      ads: [],
      lastSelector: '.ytp-ad-skip-button',
      accelerated: false,
      skipped
    });
  }

  function accelerateAd() {
    const video = getVideo();
    if (!video) return;
    const adElement = document.querySelector('.ad-showing');
    let accelerated = false;
    if (adElement && video.currentTime > 1.5) {
      video.playbackRate = 16;
      video.muted = true;
      accelerated = true;
      log('🎬 广告中:静音 + 加速');
    } else {
      video.playbackRate = 1;
      video.muted = false;
    }
    updateDebugPanel({
      ads: [],
      lastSelector: '.ad-showing',
      accelerated,
      skipped: false
    });
  }

  function observePage() {
    const observer = new MutationObserver(() => {
      hideAds();
      clickSkip();
      accelerateAd();
    });
    observer.observe(document.body, { childList: true, subtree: true });
  }

  // =============================
  //  7. 初始化
  // =============================
  function init() {
    loadLocalSelectors();
    fetchAdSelectorsFromAI();
    setInterval(fetchAdSelectorsFromAI, 60 * 60 * 1000); // 每小时更新一次
    observePage();
    log("🚀 YouTube AI 广告助手启动完成");
  }

  init();
})();

QingJ © 2025

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