// ==UserScript== // @name 🎬 智能视频解析助手 - 增强版(仅供学习参考) // @namespace https://github.com/video-helper // @version 2.1.0 // @description 专业视频解析工具 | 支持多平台 | 完全免费 | 仅供技术学习交流使用 // @author 智能解析助手 // @match *://*.iqiyi.com/* // @match *://v.qq.com/* // @match *://*.youku.com/* // @match *://*.mgtv.com/* // @match *://*.bilibili.com/* // @match *://*.le.com/* // @match *://*.sohu.com/* // @match *://*.pptv.com/* // @match *://*.1905.com/* // @grant GM_registerMenuCommand // @grant GM_addStyle // @grant GM_notification // @grant GM_getValue // @grant GM_setValue // @grant GM_openInTab // @require https://cdn.jsdelivr.net/npm/sweetalert2@11 // @run-at document-idle // @icon https://cdn.jsdelivr.net/npm/simple-icons@v8/icons/vlc.svg // @supportURL https://github.com/video-helper/issues // @license MIT // ==/UserScript== /** * 视频解析助手 - 增强版 * * 重要法律声明: * 1. 本工具为免费开源项目,仅供个人学习、研究网络技术之用。 * 2. 严禁将本工具用于任何侵犯版权、违反平台服务条款或法律法规的行为。 * 3. 用户应确保其通过本工具观看的任何内容均已获得合法授权。 * 4. 本工具完全免费,开发者不从中获取任何直接或间接收益,不构成任何形式的商业服务或担保。 * 5. 使用本工具及其中集成的任何第三方解析接口所带来的所有风险(包括但不限于安全风险、法律风险)由用户自行承担。 * 6. 开发者不对因使用本工具导致的任何内容合法性、服务可用性、数据安全性问题及由此引发的任何直接、间接或衍生损失承担任何责任。 * 7. 用户使用本工具即视为已阅读、理解并完全同意本声明,并承诺合法合规使用。 */ (function() { 'use strict'; // ==================== 配置管理模块 ==================== const ConfigManager = { // 调试模式开关 DEBUG: false, // 存储键名 STORAGE_KEYS: { AUTO_PLAY: 'video_helper_auto_play', SELECTED_API: 'video_helper_selected_api', CUSTOM_APIS: 'video_helper_custom_apis', SCRIPT_VERSION: 'video_helper_version' }, // 解析接口类型定义 API_TYPES: { EMBEDDED: '1', // 内嵌播放 POPUP_EPISODES: '2', // 弹窗带选集 POPUP_SIMPLE: '3' // 弹窗无选集 }, // 支持的视频平台 SUPPORTED_PLATFORMS: [ { name: '爱奇艺', patterns: ['iqiyi.com'], playerSelectors: ['#player', '.qiyi-player', '.player-container'] }, { name: '腾讯视频', patterns: ['v.qq.com'], playerSelectors: ['#tenvideo_video_player', '.txp_player'] }, { name: '优酷', patterns: ['youku.com'], playerSelectors: ['#player', '.yk-player'] }, { name: '芒果TV', patterns: ['mgtv.com'], playerSelectors: ['#mgtv-player-wrap', '.mgtv-player'] }, { name: '哔哩哔哩', patterns: ['bilibili.com'], playerSelectors: ['#bilibiliPlayer', '.bilibili-player'] }, { name: '乐视', patterns: ['le.com'], playerSelectors: ['#player', '.le-player'] }, { name: '搜狐视频', patterns: ['sohu.com'], playerSelectors: ['#player', '.sohu-player'] }, { name: 'PPTV', patterns: ['pptv.com'], playerSelectors: ['#player', '.pptv-player'] }, { name: '1905电影网', patterns: ['1905.com'], playerSelectors: ['#player', '.vod-player'] } ], // 内置解析接口(去重后的完整列表) BUILTIN_APIS: [ // 内嵌播放 + 弹窗无选集接口 {name: "七哥解析", type: "1,3", url: "https://jx.nnxv.cn/tv.php?url=", recommended: true}, {name: "虾米解析", type: "1,3", url: "https://jx.xmflv.cc/?url=", recommended: true}, {name: "纯净解析", type: "1,2,3", url: "https://im1907.top/?jx="}, {name: "B站解析", type: "1,3", url: "https://jx.jsonplayer.com/player/?url="}, {name: "爱豆解析", type: "1,3", url: "https://jx.aidouer.net/?url="}, {name: "BL解析", type: "1,3", url: "https://vip.bljiex.com/?v="}, {name: "冰豆解析", type: "1,3", url: "https://api.qianqi.net/vip/?url="}, {name: "百域解析", type: "1,3", url: "https://jx.618g.com/?url="}, {name: "CK解析", type: "1,3", url: "https://www.ckplayer.vip/jiexi/?url="}, {name: "CHok解析", type: "1,3", url: "https://www.gai4.com/?url="}, {name: "ckmov解析", type: "1,3", url: "https://www.ckmov.vip/api.php?url="}, {name: "H8解析", type: "1,3", url: "https://www.h8jx.com/jiexi.php?url="}, {name: "JY解析", type: "1,3", url: "https://jx.playerjy.com/?url="}, {name: "解析接口", type: "1,3", url: "https://ckmov.ccyjjd.com/ckmov/?url="}, {name: "解析la", type: "1,3", url: "https://api.jiexi.la/?url="}, {name: "老板解析", type: "1,3", url: "https://vip.laobandq.com/jiexi.php?url="}, {name: "MAO解析", type: "1,3", url: "https://www.mtosz.com/m3u8.php?url="}, {name: "M3U8解析", type: "1,3", url: "https://jx.m3u8.tv/jiexi/?url="}, {name: "诺讯解析", type: "1,3", url: "https://www.nxflv.com/?url="}, {name: "OK解析", type: "1,3", url: "https://okjx.cc/?url="}, {name: "PM解析", type: "1,3", url: "https://www.playm3u8.cn/jiexi.php?url="}, {name: "盘古解析", type: "1,3", url: "https://www.pangujiexi.cc/jiexi.php?url="}, {name: "RDHK解析", type: "1,3", url: "https://jx.rdhk.net/?v="}, {name: "人人迷解析", type: "1,3", url: "https://jx.blbo.cc:4433/?url="}, {name: "思云解析", type: "1,3", url: "https://jx.ap2p.cn/?url="}, {name: "思古解析", type: "1,3", url: "https://jsap.attakids.com/?url="}, {name: "听乐解析", type: "1,3", url: "https://jx.dj6u.com/?url="}, {name: "维多解析", type: "1,3", url: "https://jx.ivito.cn/?url="}, {name: "YT解析", type: "1,3", url: "https://jx.yangtu.top/?url="}, {name: "云端解析", type: "1,3", url: "https://sb.5gseo.net/?url="}, {name: "0523解析", type: "1,3", url: "https://go.yh0523.cn/y.cy?url="}, {name: "17云解析", type: "1,3", url: "https://www.1717yun.com/jx/ty.php?url="}, {name: "180解析", type: "1,3", url: "https://jx.000180.top/jx/?url="}, {name: "4K解析", type: "1,3", url: "https://jx.4kdv.com/?url="}, {name: "8090解析", type: "1,3", url: "https://www.8090g.cn/?url="}, {name: "剖元解析", type: "1,3", url: "https://www.pouyun.com/?url="}, {name: "全民解析", type: "1,3", url: "https://43.240.74.102:4433?url="}, {name: "夜幕解析", type: "1,3", url: "https://www.yemu.xyz/?url="}, // 弹窗播放带选集接口 {name: "im1907(带选集)", type: "2", url: "https://im1907.top/?jx="}, {name: "云析(带选集)", type: "2", url: "https://jx.yparse.com/index.php?url="}, ], // 获取所有可用的解析接口 getAllApis: function() { const uniqueApis = []; const seenUrls = new Set(); // 去重处理 this.BUILTIN_APIS.forEach(api => { if (!seenUrls.has(api.url)) { seenUrls.add(api.url); uniqueApis.push(api); } }); // 合并自定义接口 const customApis = GM_getValue(this.STORAGE_KEYS.CUSTOM_APIS, []); return [...uniqueApis, ...customApis]; }, // 检查当前网站是否支持 isSiteSupported: function() { const hostname = window.location.hostname; return this.SUPPORTED_PLATFORMS.some(platform => platform.patterns.some(pattern => hostname.includes(pattern)) ); }, // 查找视频播放器容器 findVideoContainer: function() { const platform = this.SUPPORTED_PLATFORMS.find(p => p.patterns.some(pattern => window.location.hostname.includes(pattern)) ); if (platform) { for (const selector of platform.playerSelectors) { const container = document.querySelector(selector); if (container) { this.log(`找到视频容器: ${selector}`); return container; } } } // 通用查找 const commonSelectors = [ '#player', '.player', '.video-player', '.player-container', '.video-container', 'video', 'iframe[src*="video"]' ]; for (const selector of commonSelectors) { const container = document.querySelector(selector); if (container) { this.log(`通用找到视频容器: ${selector}`); return container; } } return null; }, // 调试日志 log: function(...args) { if (this.DEBUG) { console.log('[视频解析助手]', ...args); } } }; // ==================== UI管理器模块 ==================== const UIManager = { // 生成唯一的ID generateId: function() { return 'video_helper_' + Math.random().toString(36).substr(2, 9); }, // 注入CSS样式 injectStyles: function() { const styles = ` #video-helper-container { position: fixed; top: 120px; left: 0; z-index: 2147483647; transition: left 0.3s ease; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; } #video-helper-container:hover { left: 0; } .vh-main-icon { width: 40px; height: 40px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 8px 0 0 8px; display: flex; align-items: center; justify-content: center; cursor: pointer; color: white; font-weight: bold; font-size: 14px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); user-select: none; } .vh-main-icon:hover { background: linear-gradient(135deg, #764ba2 0%, #667eea 100%); } .vh-panel { position: absolute; left: 40px; top: 0; width: 420px; background: rgba(255, 255, 255, 0.95); backdrop-filter: blur(10px); border-radius: 0 8px 8px 8px; box-shadow: 0 8px 32px rgba(0,0,0,0.2); overflow: hidden; opacity: 0; transform: translateX(-20px); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); display: none; } #video-helper-container:hover .vh-panel { opacity: 1; transform: translateX(0); display: block; } .vh-tabs { display: flex; background: #f8f9fa; border-bottom: 1px solid #e9ecef; } .vh-tab { flex: 1; padding: 12px; border: none; background: none; cursor: pointer; font-size: 12px; color: #6c757d; transition: all 0.2s; } .vh-tab.active { color: #667eea; font-weight: 600; border-bottom: 2px solid #667eea; background: white; } .vh-tab-content { padding: 16px; max-height: 400px; overflow-y: auto; } .vh-section-title { color: #667eea; font-weight: 600; font-size: 12px; margin: 12px 0 8px 0; padding-bottom: 4px; border-bottom: 1px solid #e9ecef; } .vh-api-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin-bottom: 12px; } .vh-api-item { padding: 6px 4px; background: white; border: 1px solid #dee2e6; border-radius: 4px; font-size: 11px; text-align: center; cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; transition: all 0.2s; } .vh-api-item:hover { border-color: #667eea; color: #667eea; transform: translateY(-1px); } .vh-api-item.selected { border-color: #667eea; color: #667eea; background: #f0f2ff; } .vh-api-item.recommended { border-color: #28a745; } .vh-api-item.recommended:hover { border-color: #218838; } .vh-mode-toggle { color: #667eea; font-size: 10px; cursor: pointer; margin-left: 2px; } .vh-auto-switch { width: 40px; height: 40px; background: #28a745; border-radius: 8px 0 0 8px; display: flex; align-items: center; justify-content: center; cursor: pointer; color: white; font-weight: bold; font-size: 12px; margin-top: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); } .vh-auto-switch.off { background: #dc3545; } .vh-auto-switch:hover { opacity: 0.9; } .vh-legal-notice { background: #fff3cd; border: 2px solid #ffc107; border-radius: 6px; padding: 12px; margin: 0 0 16px 0; font-size: 11px; color: #856404; text-align: left; } .vh-legal-title { font-weight: bold; font-size: 12px; margin-bottom: 6px; color: #856404; } .vh-legal-text { margin: 4px 0; line-height: 1.4; } .vh-custom-form { padding: 12px; background: #f8f9fa; border-radius: 6px; margin-top: 12px; } .vh-form-title { color: #495057; font-size: 12px; margin-bottom: 8px; } .vh-form-input { width: 100%; padding: 6px 8px; border: 1px solid #ced4da; border-radius: 4px; font-size: 12px; margin-bottom: 8px; } .vh-form-input:focus { outline: none; border-color: #667eea; } .vh-form-select { width: 100%; padding: 6px 8px; border: 1px solid #ced4da; border-radius: 4px; font-size: 12px; margin-bottom: 8px; background: white; } .vh-form-buttons { display: flex; gap: 8px; } .vh-btn { flex: 1; padding: 6px 12px; border: none; border-radius: 4px; font-size: 12px; cursor: pointer; transition: all 0.2s; } .vh-btn-primary { background: #667eea; color: white; } .vh-btn-primary:hover { background: #5a67d8; } .vh-btn-secondary { background: #6c757d; color: white; } .vh-btn-secondary:hover { background: #545b62; } .vh-notice { background: #e7f5ff; border: 1px solid #a5d8ff; border-radius: 4px; padding: 8px; margin: 8px 0; font-size: 11px; color: #1864ab; } .vh-notice-title { font-weight: bold; margin-bottom: 4px; } /* 滚动条样式 */ .vh-tab-content::-webkit-scrollbar { width: 4px; } .vh-tab-content::-webkit-scrollbar-track { background: #f1f1f1; } .vh-tab-content::-webkit-scrollbar-thumb { background: #c1c1c1; border-radius: 2px; } .vh-tab-content::-webkit-scrollbar-thumb:hover { background: #a8a8a8; } `; GM_addStyle(styles); }, // 创建主界面 createInterface: function(apis) { const containerId = this.generateId(); const container = document.createElement('div'); container.id = containerId; container.innerHTML = this.generateHTML(apis); document.body.appendChild(container); this.bindEvents(container, apis); return container; }, // 生成HTML内容 generateHTML: function(apis) { const simpleApis = apis.filter(api => api.type.includes('1') || api.type.includes('3')); const complexApis = apis.filter(api => api.type.includes('2')); return `
VIP
内嵌/弹窗播放接口
${this.generateApiItems(simpleApis)}
${complexApis.length > 0 ? `
弹窗播放(带选集)
${this.generateApiItems(complexApis)}
` : ''}
使用说明:
1. 点击接口名称进行解析
2. 内嵌接口会替换原播放器
3. 弹窗接口会在新标签页打开
4. 接口名称后的模式标签可切换播放方式
${GM_getValue(ConfigManager.STORAGE_KEYS.AUTO_PLAY) ? '开' : '关'}
`; }, // 生成接口项 generateApiItems: function(apis) { return apis.map((api, index) => { const types = api.type.split(','); let modeText = ''; let modeAttr = ''; if (types.includes('1') && types.includes('3')) { modeText = '内嵌'; modeAttr = 'data-modes="1,3" data-current-mode="1"'; } else if (types.includes('1')) { modeText = '内嵌'; modeAttr = 'data-mode="1"'; } else if (types.includes('2')) { modeText = ''; modeAttr = 'data-mode="2"'; } else if (types.includes('3')) { modeText = '弹窗'; modeAttr = 'data-mode="3"'; } const modeHtml = modeText ? ` | ${modeText}` : ''; const recommendedClass = api.recommended ? 'recommended' : ''; return `
${api.name}${modeHtml}
`; }).join(''); }, // 绑定事件 bindEvents: function(container, apis) { // 选项卡切换 container.querySelectorAll('.vh-tab').forEach(tab => { tab.addEventListener('click', () => { const tabName = tab.dataset.tab; // 更新激活状态 container.querySelectorAll('.vh-tab').forEach(t => t.classList.remove('active')); tab.classList.add('active'); // 显示对应内容 container.querySelectorAll('.vh-tab-content').forEach(content => { content.style.display = content.dataset.content === tabName ? 'block' : 'none'; }); }); }); // 接口点击事件 container.querySelectorAll('.vh-api-item').forEach(item => { item.addEventListener('click', (e) => { if (e.target.classList.contains('vh-mode-toggle')) { return; // 模式切换由单独的事件处理 } const index = parseInt(item.dataset.index); VideoHelper.useApi(apis[index], item); }); }); // 自动解析开关 container.querySelector('.vh-auto-switch').addEventListener('click', function() { const isOn = this.classList.contains('on'); if (isOn) { this.classList.remove('on'); this.classList.add('off'); this.textContent = '关'; this.title = '自动解析已关闭'; GM_setValue(ConfigManager.STORAGE_KEYS.AUTO_PLAY, false); } else { this.classList.remove('off'); this.classList.add('on'); this.textContent = '开'; this.title = '自动解析已开启'; GM_setValue(ConfigManager.STORAGE_KEYS.AUTO_PLAY, true); } // 显示通知 VideoHelper.showNotification( '设置已保存', `自动解析已${isOn ? '关闭' : '开启'}`, 'success' ); }); // 自定义接口表单 const saveBtn = container.querySelector('#save-custom-api'); if (saveBtn) { saveBtn.addEventListener('click', () => { const name = container.querySelector('#custom-api-name').value.trim(); const url = container.querySelector('#custom-api-url').value.trim(); const type = container.querySelector('#custom-api-type').value; if (!name || !url) { VideoHelper.showNotification('输入不完整', '请填写接口名称和地址', 'error'); return; } if (!url.includes('?url=') && !url.includes('&url=')) { VideoHelper.showNotification('格式错误', '接口地址必须包含 ?url= 或 &url= 参数', 'error'); return; } const newApi = { name, type, url }; const customApis = GM_getValue(ConfigManager.STORAGE_KEYS.CUSTOM_APIS, []); customApis.push(newApi); GM_setValue(ConfigManager.STORAGE_KEYS.CUSTOM_APIS, customApis); // 清空表单 container.querySelector('#custom-api-name').value = ''; container.querySelector('#custom-api-url').value = ''; VideoHelper.showNotification('添加成功', '自定义接口已保存,刷新页面后生效', 'success'); }); } // 清空自定义接口 const clearBtn = container.querySelector('#clear-custom-apis'); if (clearBtn) { clearBtn.addEventListener('click', () => { Swal.fire({ title: '确认清空?', text: '这将删除所有自定义解析接口', icon: 'warning', showCancelButton: true, confirmButtonText: '确认清空', cancelButtonText: '取消' }).then(result => { if (result.isConfirmed) { GM_setValue(ConfigManager.STORAGE_KEYS.CUSTOM_APIS, []); VideoHelper.showNotification('已清空', '所有自定义接口已被删除', 'success'); } }); }); } // 拖拽功能 this.enableDragging(container); }, // 启用拖拽 enableDragging: function(container) { let isDragging = false; let startX, startY, startLeft, startTop; container.querySelector('.vh-main-icon').addEventListener('mousedown', startDrag); function startDrag(e) { if (e.target.classList.contains('vh-mode-toggle')) { return; } isDragging = true; startX = e.clientX; startY = e.clientY; const rect = container.getBoundingClientRect(); startLeft = rect.left; startTop = rect.top; document.addEventListener('mousemove', drag); document.addEventListener('mouseup', stopDrag); e.preventDefault(); } function drag(e) { if (!isDragging) return; const deltaX = e.clientX - startX; const deltaY = e.clientY - startY; let newLeft = startLeft + deltaX; let newTop = startTop + deltaY; // 边界检查 newLeft = Math.max(0, Math.min(newLeft, window.innerWidth - 40)); newTop = Math.max(0, Math.min(newTop, window.innerHeight - 48)); container.style.left = newLeft + 'px'; container.style.top = newTop + 'px'; } function stopDrag() { isDragging = false; document.removeEventListener('mousemove', drag); document.removeEventListener('mouseup', stopDrag); } } }; // ==================== 主功能模块 ==================== const VideoHelper = { // 初始化 init: function() { try { ConfigManager.log('视频解析助手初始化...'); // 检查是否支持当前网站 if (!ConfigManager.isSiteSupported()) { ConfigManager.log('当前网站不支持,跳过初始化'); return; } // 注入样式 UIManager.injectStyles(); // 获取所有接口 const allApis = ConfigManager.getAllApis(); ConfigManager.log(`加载了 ${allApis.length} 个解析接口`); // 创建界面 UIManager.createInterface(allApis); // 注册菜单 this.registerMenuCommands(); // 检查自动播放 this.checkAutoPlay(allApis); ConfigManager.log('初始化完成'); } catch (error) { console.error('视频解析助手初始化失败:', error); } }, // 使用解析接口 useApi: function(api, element) { try { ConfigManager.log(`使用解析接口: ${api.name}`); // 获取播放模式 let playMode = this.getPlayMode(element, api); // 保存选择的接口 const allApis = ConfigManager.getAllApis(); const index = allApis.findIndex(a => a.url === api.url); if (index !== -1) { GM_setValue(ConfigManager.STORAGE_KEYS.SELECTED_API, index); } // 根据模式处理 if (playMode === ConfigManager.API_TYPES.EMBEDDED) { this.embedPlay(api); } else { this.popupPlay(api); } // 更新选中状态 document.querySelectorAll('.vh-api-item').forEach(item => { item.classList.remove('selected'); }); if (element) { element.classList.add('selected'); } } catch (error) { ConfigManager.log('解析接口使用失败:', error); this.showNotification('解析失败', '请尝试其他接口或稍后重试', 'error'); } }, // 获取播放模式 getPlayMode: function(element, api) { if (!element) return api.type.split(',')[0]; if (element.hasAttribute('data-modes')) { return element.getAttribute('data-current-mode') || '1'; } else if (element.hasAttribute('data-mode')) { return element.getAttribute('data-mode'); } return api.type.split(',')[0]; }, // 内嵌播放 embedPlay: function(api) { const container = ConfigManager.findVideoContainer(); if (!container) { this.showNotification('未找到播放器', '无法定位视频播放区域,请刷新页面重试', 'warning'); return; } // 清空容器 while (container.firstChild) { container.removeChild(container.firstChild); } // 创建iframe const iframe = document.createElement('iframe'); iframe.src = api.url + encodeURIComponent(window.location.href); iframe.style.width = '100%'; iframe.style.height = '100%'; iframe.style.border = 'none'; iframe.allowFullscreen = true; iframe.setAttribute('allow', 'autoplay; fullscreen'); // 设置容器样式 container.style.position = 'relative'; container.style.width = '100%'; container.style.height = '100%'; container.style.zIndex = '999999'; container.appendChild(iframe); this.showNotification('解析成功', `正在使用 ${api.name} 播放`, 'success'); }, // 弹窗播放 popupPlay: function(api) { const url = api.url + encodeURIComponent(window.location.href); GM_openInTab(url, { active: true, insert: true, setParent: true }); this.showNotification('正在打开', `使用 ${api.name} 在新标签页播放`, 'info'); }, // 切换播放模式 toggleMode: function(element) { const modes = element.parentElement.getAttribute('data-modes').split(','); const currentMode = element.parentElement.getAttribute('data-current-mode'); let nextIndex = modes.indexOf(currentMode) + 1; if (nextIndex >= modes.length) nextIndex = 0; const nextMode = modes[nextIndex]; element.parentElement.setAttribute('data-current-mode', nextMode); let modeText = nextMode === '1' ? '内嵌' : '弹窗'; element.textContent = modeText; this.showNotification('模式切换', `已切换为${modeText}播放模式`, 'info'); }, // 检查自动播放 checkAutoPlay: function(apis) { if (!GM_getValue(ConfigManager.STORAGE_KEYS.AUTO_PLAY)) { return; } const selectedIndex = GM_getValue(ConfigManager.STORAGE_KEYS.SELECTED_API, 0); if (selectedIndex >= 0 && selectedIndex < apis.length) { const api = apis[selectedIndex]; // 只对内嵌播放接口启用自动播放 if (api.type.includes('1')) { setTimeout(() => { this.useApi(api); ConfigManager.log('自动播放已触发'); }, 2000); } } }, // 注册菜单命令 registerMenuCommands: function() { try { GM_registerMenuCommand('🎬 显示解析面板', () => { const container = document.getElementById('video-helper-container'); if (container) { container.style.display = 'block'; } }); GM_registerMenuCommand('⚙️ 工具设置', () => { Swal.fire({ title: '视频解析助手', html: `

版本:2.1.0

接口数量:${ConfigManager.getAllApis().length}

自动解析:${GM_getValue(ConfigManager.STORAGE_KEYS.AUTO_PLAY) ? '已开启' : '已关闭'}

支持平台:${ConfigManager.SUPPORTED_PLATFORMS.length}个

性质:免费开源,仅供技术学习

`, icon: 'info' }); }); GM_registerMenuCommand('📋 自定义接口', () => { const container = document.getElementById('video-helper-container'); if (container) { container.style.display = 'block'; container.querySelector('[data-tab="custom"]').click(); } }); ConfigManager.log('菜单命令已注册'); } catch (error) { ConfigManager.log('菜单命令注册失败:', error); } }, // 显示通知 showNotification: function(title, message, icon = 'info') { Swal.fire({ title: title, text: message, icon: icon, toast: true, position: 'top-end', showConfirmButton: false, timer: 2000, timerProgressBar: true }); } }; // ==================== 初始化执行 ==================== // 等待页面加载完成 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => VideoHelper.init()); } else { VideoHelper.init(); } // 暴露全局对象(仅用于调试) if (ConfigManager.DEBUG) { window.VideoHelper = VideoHelper; window.ConfigManager = ConfigManager; window.UIManager = UIManager; } })();