// ==UserScript== // @name 全网VIP视频免费破解去广告-V1.3完美版 // @namespace http://tampermonkey.net/ // @version 1.1 // @description 🔥全能解析终极版!【无广告+小窗屏蔽+极速解析】支持优酷/爱奇艺/腾讯/B站等全网VIP视频。自带接口测速、自动贴边、手机电脑双端完美兼容。 // @author 小哲(Gemini-3-pro辅助开发) // @icon https://v.qq.com/favicon.ico // @tag VIP解析 // @tag 视频破解 // @tag 去广告 // @tag 屏蔽小窗 // @match *://*.youku.com/* // @match *://*.iqiyi.com/* // @match *://*.iq.com/* // @match *://*.le.com/* // @match *://v.qq.com/* // @match *://m.v.qq.com/* // @match *://*.tudou.com/* // @match *://*.mgtv.com/* // @match *://tv.sohu.com/* // @match *://film.sohu.com/* // @match *://*.1905.com/* // @match *://*.bilibili.com/* // @match *://*.pptv.com/* // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // @grant GM_xmlhttpRequest // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @run-at document-end // @license MIT // ==/UserScript== (function() { 'use strict'; // ================= 🛑 关键修复:防多开机制 ================= // 如果当前窗口不是顶层窗口(是在iframe里),直接退出,不运行! if (window.top !== window.self) { return; } console.log('Gemini-VIP-Script: 正在主窗口启动...'); // ================= ⚙️ 配置中心 ================= const DEFAULT_APIS = [ { name: "虾米 (推荐)", url: "https://jx.xmflv.com/?url=" }, { name: "虾米2 (备用)", url: "https://jx.xmflv.cc/?url=" }, { name: "纯净解析", url: "https://im1907.top/?jx=" }, { name: "B站专用", url: "https://jx.jsonplayer.com/player/?url=" }, { name: "咸鱼云", url: "https://jx.xymp4.cc/?url=" }, { name: "爱豆", url: "https://jx.aidouer.net/?url=" }, { name: "CHok", url: "https://www.gai4.com/?url=" }, { name: "OK解析", url: "https://okjx.cc/?url=" }, { name: "RDHK", url: "https://jx.rdhk.net/?v=" }, { name: "人人迷", url: "https://jx.blbo.cc:4433/?url=" }, { name: "思古3", url: "https://jsap.attakids.com/?url=" }, { name: "听乐", url: "https://jx.dj6u.com/?url=" }, { name: "YT", url: "https://jx.yangtu.top/?url=" } ]; const DEFAULT_CONFIG = { autoSnap: true, openInNewTab: true, embedMode: true, autoSync: true, antiMini: true, idleOpacity: true, shortcut: true, darkMode: 'auto', posPct: { x: 2, y: 30 }, lastApi: '', apis: DEFAULT_APIS, agreedDisclaimer: true, version: '1.3' }; // ================= 🧠 状态管理 ================= const State = { get: () => { try { const saved = GM_getValue('config', {}); if (!saved.posPct || isNaN(saved.posPct.x)) saved.posPct = { x: 2, y: 30 }; saved.agreedDisclaimer = true; return { ...DEFAULT_CONFIG, ...saved }; } catch (e) { return DEFAULT_CONFIG; } }, set: (newConfig) => GM_setValue('config', newConfig), update: (key, value) => { const config = State.get(); config[key] = value; State.set(config); return config; } }; // ================= 🎨 UI 构建 ================= const CONTAINER_ID = 'gemini-vip-pro-fix-v1-3'; // 暴力清理旧版本ID,防止残留 ['gemini-vip-pro-v1-0', 'gemini-vip-pro-force-v1-2'].forEach(id => { const old = document.getElementById(id); if(old) old.remove(); }); let container = document.getElementById(CONTAINER_ID); if (!container) { container = document.createElement('div'); container.id = CONTAINER_ID; (document.documentElement || document.body).appendChild(container); } const shadow = container.attachShadow({ mode: 'open' }); const getStyles = (isDark) => ` :host { --primary: #3B82F6; --primary-grad: linear-gradient(135deg, #3B82F6 0%, #7C3AED 100%); --warn: #EF4444; --success: #10B981; --warning: #F59E0B; --bg-blur: ${isDark ? 'rgba(30, 30, 30, 0.95)' : 'rgba(255, 255, 255, 0.95)'}; --text-main: ${isDark ? '#F3F4F6' : '#1F2937'}; --text-sub: ${isDark ? '#9CA3AF' : '#6B7280'}; --border: ${isDark ? 'rgba(255,255,255,0.1)' : 'rgba(255,255,255,0.6)'}; --hover-bg: ${isDark ? 'rgba(255,255,255,0.08)' : 'rgba(0,0,0,0.04)'}; position: fixed; top: 0; left: 0; z-index: 2147483647; font-family: system-ui, -apple-system, sans-serif; font-size: 14px; pointer-events: none; color: var(--text-main); width: 100vw; height: 100vh; overflow: visible; display: block !important; } .wrapper { position: absolute; width: 50px; height: 50px; pointer-events: auto; display: block !important; z-index: 2147483647; /* 默认位置 */ top: 30%; left: 10px; } .float-ball { width: 50px; height: 50px; background: var(--primary-grad); border-radius: 50%; box-shadow: 0 4px 15px rgba(59, 130, 246, 0.4); cursor: pointer; display: flex; justify-content: center; align-items: center; transition: transform 0.2s, opacity 0.3s, filter 0.3s; border: 2px solid rgba(255,255,255,0.2); backdrop-filter: blur(4px); } .float-ball:hover { transform: scale(1.1); } .float-ball:active { transform: scale(0.95); } .float-ball.idle { opacity: 0.5; filter: grayscale(0.5); transform: scale(0.9); } .ball-icon { width: 24px; height: 24px; fill: white; transition: transform 0.3s; } .wrapper.active .ball-icon { transform: rotate(90deg); } .menu-panel { position: absolute; top: 0; width: 300px; background: var(--bg-blur); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); border-radius: 18px; box-shadow: 0 10px 40px rgba(0,0,0,0.2); border: 1px solid var(--border); display: none; flex-direction: column; overflow: hidden; animation: menuIn 0.25s cubic-bezier(0.2, 0.8, 0.2, 1); } @keyframes menuIn { from { opacity: 0; transform: scale(0.95) translateY(-10px); } to { opacity: 1; transform: scale(1) translateY(0); } } .pos-right .menu-panel { right: 60px; left: auto; transform-origin: top right; } .pos-left .menu-panel { left: 60px; right: auto; transform-origin: top left; } .menu-header { padding: 16px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid var(--hover-bg); } .app-name { font-weight: 800; font-size: 15px; background: var(--primary-grad); -webkit-background-clip: text; -webkit-text-fill-color: transparent; } .tools { display: flex; gap: 4px; } .icon-btn { width: 28px; height: 28px; border-radius: 8px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.2s; fill: var(--text-sub); } .icon-btn:hover { background: var(--hover-bg); fill: var(--primary); } .icon-btn.testing { animation: spin 1s linear infinite; fill: var(--primary); pointer-events: none; } @keyframes spin { 100% { transform: rotate(360deg); } } .content-view { display: none; padding: 15px; max-height: 360px; overflow-y: auto; } .content-view.active { display: block; animation: fadeIn 0.2s; } .alert-box { margin: 10px 12px 0 12px; padding: 10px; background: ${isDark ? 'rgba(239, 68, 68, 0.15)' : '#FEF2F2'}; border: 1px solid ${isDark ? 'rgba(239, 68, 68, 0.3)' : '#FECACA'}; border-radius: 10px; color: var(--warn); font-size: 12px; display: flex; gap: 8px; align-items: start; cursor: pointer; line-height: 1.4; } .api-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; } .api-item { padding: 12px 8px; border-radius: 10px; background: var(--hover-bg); border: 1px solid transparent; font-size: 13px; text-align: center; cursor: pointer; transition: all 0.2s; position: relative; color: var(--text-main) !important; font-weight: 500; display: flex; flex-direction: column; gap: 4px; } .api-item:hover { background: transparent; border-color: var(--primary); color: var(--primary) !important; transform: translateY(-2px); } .api-item.current { background: var(--primary-grad); color: white !important; } .ping-tag { font-size: 10px; font-weight: normal; opacity: 0.8; } .ping-green { color: var(--success); } .ping-yellow { color: var(--warning); } .ping-red { color: var(--warn); } .current .ping-tag { color: rgba(255,255,255,0.9); } .footer { padding: 10px; text-align: center; border-top: 1px solid var(--hover-bg); font-size: 11px; color: var(--text-sub); } .link { color: var(--primary); text-decoration: none; display: inline-flex; align-items: center; cursor: pointer; transition: 0.2s; } .link:hover { opacity: 0.8; } .set-row { display: flex; justify-content: space-between; align-items: center; padding: 12px 0; border-bottom: 1px solid var(--hover-bg); } .toggle { width: 42px; height: 22px; background: ${isDark ? '#4B5563' : '#E5E7EB'}; border-radius: 20px; position: relative; cursor: pointer; transition: 0.3s; } .toggle::after { content: ''; position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; background: white; border-radius: 50%; transition: 0.3s; box-shadow: 0 1px 2px rgba(0,0,0,0.2); } .toggle.checked { background: var(--primary); } .toggle.checked::after { transform: translateX(20px); } .mode-switch { display: flex; background: var(--hover-bg); padding: 3px; border-radius: 8px; } .mode-btn { flex: 1; text-align: center; padding: 4px; font-size: 12px; cursor: pointer; border-radius: 6px; color: var(--text-sub); transition: 0.2s; } .mode-btn.active { background: var(--bg-blur); color: var(--primary); font-weight: bold; } .toast { position: fixed; top: 40%; left: 50%; transform: translate(-50%, -50%); background: rgba(0,0,0,0.9); color: white; padding: 12px 24px; border-radius: 50px; opacity: 0; pointer-events: none; transition: 0.3s; z-index: 2147483647; } .toast.show { opacity: 1; transform: translate(-50%, -60%); } `; const styleElement = document.createElement('style'); shadow.appendChild(styleElement); function updateTheme() { const config = State.get(); let isDark = config.darkMode === 'auto' ? (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) : (config.darkMode === 'dark'); styleElement.textContent = getStyles(isDark); } const ICONS = { play: ``, close: ``, gear: ``, edit: ``, back: ``, cross: ``, speed: `` }; const wrapper = document.createElement('div'); wrapper.className = 'wrapper'; const ball = document.createElement('div'); ball.className = 'float-ball'; ball.innerHTML = ICONS.play; ball.title = 'VIP解析'; const menu = document.createElement('div'); menu.className = 'menu-panel'; const toast = document.createElement('div'); toast.className = 'toast'; // 强制注册命令 GM_registerMenuCommand("♻️ 重置悬浮球位置", () => { State.update('posPct', { x: 2, y: 30 }); location.reload(); }); GM_registerMenuCommand("🔨 强制渲染 UI", () => { launchUI(); showToast('已强制重新渲染'); }); function init() { console.log('Gemini-VIP: Init...'); launchUI(); if (State.get().antiMini) injectAntiMiniStyles(); setupUrlListener(); } // ================= ⚡ 测速核心逻辑 ================= function testLatency(url) { return new Promise(resolve => { const start = Date.now(); GM_xmlhttpRequest({ method: 'GET', url: url, timeout: 3000, headers: { 'Cache-Control': 'no-cache' }, onload: (res) => { const time = Date.now() - start; if (res.status >= 200 && res.status < 400) resolve(time); else resolve(-1); }, onerror: () => resolve(-1), ontimeout: () => resolve(-1) }); }); } async function runSpeedTest() { const btn = menu.querySelector('#btn-speed'); if(btn.classList.contains('testing')) return; btn.classList.add('testing'); showToast('🚀 开始智能测速...'); const items = menu.querySelectorAll('.api-item'); const tasks = Array.from(items).map(async (item) => { const url = item.dataset.url; const tag = item.querySelector('.ping-tag'); tag.textContent = '检测中...'; tag.className = 'ping-tag'; const testUrl = url.includes('?') ? url : (url + '?'); const ms = await testLatency(testUrl); if (ms === -1) { tag.textContent = '超时/故障'; tag.classList.add('ping-red'); } else { tag.textContent = ms + 'ms'; if(ms < 500) tag.classList.add('ping-green'); else if(ms < 1500) tag.classList.add('ping-yellow'); else tag.classList.add('ping-red'); } }); await Promise.all(tasks); btn.classList.remove('testing'); showToast('✅ 测速完成'); } // ================= 🔮 核心:全局天眼 & 防小窗系统 ================= let overlayUpdateTimer = null; function safeOpen(baseUrl, name) { const config = State.update('lastApi', baseUrl); const targetUrl = baseUrl + location.href; if (config.embedMode) { showToast(`📺 正在覆盖解析: ${name}`); toggleMenu(false); setTimeout(() => coverPlayerGlobal(targetUrl), 200); } else { showToast(`🚀 正在新标签页解析: ${name}`); setTimeout(() => { config.openInNewTab ? window.open(targetUrl, '_blank') : location.href = targetUrl; toggleMenu(false); }, 500); } } function findVideoElement() { const video = document.querySelector('video'); if (video) return video; const selectors = ['#player', '.player-container', '#mod_player', '#bilibili-player', '.iqp-player', '#mgtv-player-wrap']; for (let sel of selectors) { const el = document.querySelector(sel); if (el && el.clientWidth > 100) return el; } return null; } function injectAntiMiniStyles() { if (!document.getElementById('gemini-anti-mini-style')) { const style = document.createElement('style'); style.id = 'gemini-anti-mini-style'; style.textContent = ` .txp_player_mini, .txp_mini_player, .txp-pip-player, .txp-player-mini-container { display: none !important; } .bilibili-player-video-float, .mini-player, .bpx-player-container[data-screen="mini"] { display: none !important; } .mini-player, .yp-player-mini, .iqp-player-mini, .iqp-player.mini, .pip-mode, .float-player { display: none !important; } .mgtv-player-mini, .mgtv-pip-player, .mini-player-mask { display: none !important; } #mini-player, .player-mini { display: none !important; } `; document.head.appendChild(style); } } function removeAntiMiniStyles() { const s = document.getElementById('gemini-anti-mini-style'); if(s) s.remove(); } function coverPlayerGlobal(url) { const targetEl = findVideoElement(); if (!targetEl) { showToast('❌ 未找到播放器,尝试弹窗播放'); window.open(url, '_blank'); return; } if (State.get().antiMini) injectAntiMiniStyles(); if(window.muteInterval) clearInterval(window.muteInterval); window.muteInterval = setInterval(() => { document.querySelectorAll('video').forEach(v => { if (!v.muted || !v.paused) { v.muted = true; v.pause(); v.volume = 0; } }); }, 1500); let overlayId = 'gemini-global-overlay'; let overlay = document.getElementById(overlayId); if (!overlay) { overlay = document.createElement('div'); overlay.id = overlayId; overlay.style.cssText = ` position: absolute; z-index: 2147483646; background: #000; display: flex; flex-direction: column; overflow: hidden; `; const toolbar = document.createElement('div'); toolbar.style.cssText = `height: 0; position: absolute; top:0; right:0; z-index: 2147483648;`; toolbar.innerHTML = `