// ==UserScript== // @name B站字幕获取、AI分析及广告跳过工具 // @namespace http://tampermonkey.net/ // @version 2.4.2 // @description 实现字幕提取、AI内容总结(并可追问)、植入广告自动识别自动跳过,并依据评论区热门评论进行舆情分析。 // @author LiuMashiro // @license MIT // @match *://www.bilibili.com/video/* // @match *://www.bilibili.com/list/watchlater* // @match *://www.bilibili.com/bangumi/play/ep* // @match *://www.bilibili.com/bangumi/play/ss* // @grant GM_addStyle // @grant GM_setClipboard // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @grant GM_listValues // @grant GM_xmlhttpRequest // @grant GM_getResourceText // @grant unsafeWindow // @connect api.deepseek.com // @connect open.bigmodel.cn // @connect ark.cn-beijing.volces.com // @connect api.openai.com // @connect api.anthropic.com // @connect generativelanguage.googleapis.com // @connect raw.githubusercontent.com // @connect scriptcat.org // @connect cdn.jsdelivr.net // @connect * // @require https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js // @require https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js // @require https://cdn.jsdelivr.net/npm/pinyin-pro@3.28.1/dist/index.js // @resource KATEX_CSS https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css // @run-at document-idle // ==/UserScript== (function () { 'use strict'; // ===================== 1. 常量配置 ===================== const SCRIPT_VERSION = '2.4.2'; const GITHUB_REPO_URL = 'https://github.com/LiuMashiro/Bilibili-Subtitle-Extraction-AI-Summary-Ad-Skipping/tree/main'; const GREASYFORK_URL = 'https://greasyfork.org/zh-CN/scripts/579482'; const SCRIPTCAT_URL = 'https://scriptcat.org/zh-CN/script-show-page/6728'; const CHANGELOG_RAW_URL = 'https://raw.githubusercontent.com/LiuMashiro/Bilibili-Subtitle-Extraction-AI-Summary-Ad-Skipping/main/CHANGELOG.md'; const AD_KEYWORD_LIST = ['转转', '追觅', '神奇小鹿', '妙界', '拼多多', '加速器', '得物', '萌牙家', '夏凉被', '小冰被', '欧莱雅', '海蓝之谜', '洗发水', '防脱发产品', '洗面奶', '扫地机器人', '蓝盒子', '黑白调', '西昊', '按摩仪', '笑容加', '牙刷', '618', '双十一', '云鲸', '徕芬', 'UWANT 友望', '慕思', '珀莱雅', '鱼油']; const AD_MARK_COLOR = 'rgba(255, 193, 7, 0.6)'; const AD_CHECK_INTERVAL_MS = 2000; const AUTO_FETCH_DELAY_MS = 1500; const API_PLATFORMS = { deepseek: { name: 'DeepSeek (性价比高)', url: 'https://api.deepseek.com/v1/chat/completions', models: ['deepseek-v4-flash', 'deepseek-v4-pro', '自定义'], link: 'https://platform.deepseek.com/' }, zlm: { name: '智谱 (提供免费模型)', url: 'https://open.bigmodel.cn/api/paas/v4/chat/completions', models: ['GLM-4.7-Flash (免费)', 'GLM-5.2', 'GLM-5.1', 'GLM-5', 'GLM-5-Turbo', 'GLM-4.7', 'GLM-4.7-FlashX', 'GLM-4.6', 'GLM-4.5-Air', 'GLM-4.5-AirX', 'GLM-4-Long', 'GLM-4-FlashX-250414', 'GLM-4-Flash-250414', '自定义'], link: 'https://bigmodel.cn/' }, doubao: { name: '火山方舟 (豆包)', url: 'https://ark.cn-beijing.volces.com/api/v3/chat/completions', models: ['doubao-seed-2-0-lite-260428', 'doubao-seed-2-0-mini-260428', 'doubao-seed-2-0-pro-260215', '自定义'], link: 'https://www.volcengine.com/product/ark' }, chatgpt: { name: 'ChatGPT', url: 'https://api.openai.com/v1/chat/completions', models: ['gpt-5.5', 'gpt-5.5-pro', 'gpt-5.4', 'gpt-5.4-mini', 'gpt-5.4-nano', 'gpt-5.4-pro', '自定义'], link: 'https://platform.openai.com/' }, claude: { name: 'Claude', url: 'https://api.anthropic.com/v1/messages', models: ['claude-sonnet-4-6', 'claude-opus-4-8', 'claude-fable-5', 'claude-mythos-5', 'claude-haiku-4-5-20251001', '自定义'], link: 'https://console.anthropic.com/' }, gemini: { name: 'Gemini', url: 'https://generativelanguage.googleapis.com/v1beta/models/{model_name}:generateContent', models: ['gemini-3.1-pro-preview', 'gemini-3.5-flash', 'gemini-3-flash-preview', 'gemini-3.1-flash-lite', 'gemini-3.1-flash-lite-preview', 'gemini-2.5-flash', 'gemini-2.5-flash-lite', 'gemini-2.5-pro', '自定义'], link: 'https://aistudio.google.com/' }, custom: { name: '自定义', url: '', models: ['自定义'], link: '' } }; const TAB_OPTIONS = { preview: '浏览', ai: 'AI分析', text: '文本' }; const DETAIL_LEVELS = { very_detailed: '非常详细', detailed: '详细', concise: '简洁', minimal: '极简' }; const TAB_ORDER = ['preview', 'ai', 'text', 'settings']; // ===================== 2. 设置迁移与读取 ===================== function migrateOldSettings() { const keyMap = { bse_platform: 'bseas_platform', bse_api_url: 'bseas_api_url', bse_model: 'bseas_model', bse_auto_summary: 'bseas_auto_summary', bse_auto_open_panel: 'bseas_auto_open_panel', bse_auto_open_tab: 'bseas_auto_open_tab', bse_opinion_analysis: 'bseas_opinion_analysis', bse_opinion_comments_count: 'bseas_opinion_comments_count', bse_detail_level: 'bseas_detail_level', bse_auto_skip_ad: 'bseas_auto_skip_ad' }; for (const [oldK, newK] of Object.entries(keyMap)) { if (GM_getValue(oldK, undefined) !== undefined && GM_getValue(newK, undefined) === undefined) { GM_setValue(newK, GM_getValue(oldK)); } } const oldGlobalKey = GM_getValue('bse_api_key', ''); if (oldGlobalKey) { const plat = GM_getValue('bseas_platform', 'deepseek'); if (!GM_getValue('bseas_api_key_' + plat, '')) GM_setValue('bseas_api_key_' + plat, oldGlobalKey); } for (const k of GM_listValues()) { if (k.startsWith('bse_api_key_')) { const newK = 'bseas_' + k.slice(4); if (GM_getValue(newK, undefined) === undefined) GM_setValue(newK, GM_getValue(k)); } } } migrateOldSettings(); let bseas_platform = GM_getValue('bseas_platform', 'deepseek'); let bseas_api_key = GM_getValue('bseas_api_key_' + bseas_platform, ''); let bseas_api_url = GM_getValue('bseas_api_url', API_PLATFORMS.deepseek.url); let bseas_model = GM_getValue('bseas_model', 'deepseek-v4-flash'); let bseas_auto_summary = GM_getValue('bseas_auto_summary', false); let bseas_auto_open_panel = GM_getValue('bseas_auto_open_panel', true); let bseas_auto_open_tab = GM_getValue('bseas_auto_open_tab', 'preview'); let bseas_opinion_analysis = GM_getValue('bseas_opinion_analysis', true); let bseas_opinion_comments_count = GM_getValue('bseas_opinion_comments_count', 30); let bseas_detail_level = GM_getValue('bseas_detail_level', 'concise'); let bseas_auto_skip_ad = GM_getValue('bseas_auto_skip_ad', true); const bseas_latex = true; let bseas_disable_api = GM_getValue('bseas_disable_api', false); let bseas_panel_pos_preset = GM_getValue('bseas_panel_pos_preset', 'top-right'); let bseas_max_preview_subtitles = GM_getValue('bseas_max_preview_subtitles', 600); if (bseas_max_preview_subtitles === 200) { bseas_max_preview_subtitles = 600; GM_setValue('bseas_max_preview_subtitles', 600); } let bseas_confirm_chars = GM_getValue('bseas_confirm_chars', 20000); let bseas_confirm_enabled = GM_getValue('bseas_confirm_enabled', true); let bseas_ai_evaluation = GM_getValue('bseas_ai_evaluation', false); let bseas_save_tokens = GM_getValue('bseas_save_tokens', false); let bseas_update_mode = GM_getValue('bseas_update_mode', 'reduced'); let bseas_update_last_prompt_ts = GM_getValue('bseas_update_last_prompt_ts', 0); // ===================== 3. AI 提示词 ===================== function getFormatRules() { const latexLine = bseas_latex ? '- LaTeX 行内公式:$公式$\n- LaTeX 块级公式:$$公式$$' : ''; const latexBan = bseas_latex ? '' : '- 任何 LaTeX 公式(禁止使用 $ 符号包裹公式,数学概念请用文字或代码描述)'; return `允许使用的 Markdown 格式(仅限以下几种): - 标题:#、##、###(最多三级,禁止四级及以上) - 粗体:**文字** - 斜体:*文字* - 无序列表:- 或 * - 有序列表:1. 2. 3. - 引用:> - 分割线:--- - 行内代码:\`代码\` ${latexLine} 禁止使用的格式: - 任何 HTML 标签(如