// ==UserScript== // @name 常看VIP视频全网解析 (PRO版) // @namespace https://scriptcat.org/zh-CN/script-show-page/6457 // @version 2.6.0 // @description 💎💎💎大版本更新💎💎💎 | 💎VIP视频解析 | 🎬爱奇艺解析 | 全面支持移动端 | 🔍腾讯VIP去广 | 📺优酷独播解锁 | ⚡芒果TV大会员 | 🎥B站番剧解析 | 🔗搜狐视频直连 | ✦乐视超清播放 | ◆PPTV聚力解析 | ●咪咕体育直播 | ★西瓜VIP解锁 | 🔍抖音短剧解析 | 🎬快手短视频解析 | 📺1905电影网 | ⚡AcFun弹幕解析 | 🔗土豆/风行/暴风兼容 | ✦全网影视通解 | ◆4K蓝光画质 | ●HDR杜比音效 | ★智能线路优选 | 💎免登录免费看 | 🎞️热播剧/最新电影/独家综艺/国漫日番 | ⚡极速评估 | 🔄智能缓存 | 🚀DNS预解析 | 🚀24并发加速 | ▶Google Shaka播放器引擎 | 全面支持移动端 // @icon data:image/png;base64,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 // @author lsym // @noframes // @match *://*/* // @match *://m.*/* // @match *://*.m.*/* // @match *://*.youku.com/* // @match *://*.iqiyi.com/* // @match *://*.qq.com/* // @match *://*.bilibili.com/* // @match *://*.mgtv.com/* // @match *://*.le.com/* // @match *://*.sohu.com/* // @match *://*.pptv.com/* // @match *://*.acfun.cn/* // @match *://*.ixigua.com/* // @match *://*.douyin.com/* // @match *://*.kuaishou.com/* // @grant GM_addStyle // @grant GM_xmlhttpRequest // @grant GM_setValue // @grant GM_getValue // @grant GM_listValues // @grant GM_deleteValue // @grant GM_registerMenuCommand // @run-at document-end // @connect 360zy.com // @connect jsdelivr.com // @connect api.1080zyku.com // @connect api.apibdzy.com // @connect api.ffzyapi.com // @connect api.guangsuapi.com // @connect api.maoyanapi.top // @connect api.niuniuzy.me // @connect api.okzyw.net // @connect api.tiankongapi.com // @connect api.ukuapi.com // @connect api.ukuapi88.com // @connect api.wujinapi.me // @connect api.xinlangapi.com // @connect api.yparse.com // @connect api.yzzy-api.com // @connect api.zuidapi.com // @connect caiji.dyttzyapi.com // @connect caiji.kczyapi.com // @connect caiji.kuaichezy.org // @connect caiji.moduapi.cc // @connect cj.ffzyapi.com // @connect cj.lziapi.com // @connect cj.rycjapi.com // @connect cj.vodimg.top // @connect cj.yayazy.net // @connect ckzy.me // @connect ddmf.net // @connect hhzyapi.com // @connect ikunzyapi.com // @connect iqiyizyapi.com // @connect jszyapi.com // @connect jyzyapi.com // @connect lz.118318.xyz // @connect m3u8.apiyhzy.com // @connect p2100.net // @connect savviuux.hk3.345888.xyz.cdn.cloudflare.net // @connect sdzyapi.com // @connect slapibf.com // @connect subocaiji.com // @connect suboziyuan.net // @connect suoniapi.com // @connect taopianapi.com // @connect tyyszyapi.com // @connect www.39kan.com // @connect www.hongniuzy2.com // @connect www.huyaapi.com // @connect www.lovedan.net // @connect www.lzzy.tv // @connect www.mdzyapi.com // @connect www.qilinzyz.com // @connect www.ryzyw.com // @connect www.seacms.org // @connect www.wyvod.com // @connect xkanzy.com // @connect xsd.sdzyapi.com // @connect fastly.jsdelivr.net // @connect cdn.jsdelivr.net // @connect unpkg.com // @connect gcore.jsdelivr.net // @connect cdnjs.cloudflare.com // @connect doh.pub // @connect dns.alidns.com // @connect doh.360.cn // @connect doh.baidu.com // @connect cloudflare-dns.com // @connect dns.google // @connect dns.quad9.net // @connect tyyszy.com // @connect cj.lzcaiji.com // @connect suoniapi.com // @connect ckzy.me // @connect zuidazy.me // @connect bfzyapi.com // @connect api.wujinapi.com // @connect m3u8.apiyhzy.com // @connect caiji.maotaizy.cc // @connect caiji.kuaichezy.org // @connect xsd.sdzyapi.com // @connect subocaiji.com // @connect jinyingzy.com // @connect suoniapi.com // @connect m3u8.tiankongapi.com // @connect sdzyapi.com // @connect suoniapi.com // @connect ikunzyapi.com // @connect hhzyapi.com // @connect cj.jusj.top // @connect api.juliang.live // @connect caiji.xgzyapi.com // @antifeature piracy // @license MIT // ==/UserScript== (function () { if (window.hasInitVipScript) return; window.hasInitVipScript = true; 'use strict'; // >>> QQ_AD_GUARD_BEGIN // 腾讯视频(m.v.qq.com)拉起App广告屏蔽: // 播放页点击空白处触发 PullApp -> 拉起 txvideo:// 失败 -> 回退 location.href 跳转 // https://m.v.qq.com/activity/downapp_activity.html?not_auto_open=1(下载App广告页) (function () { if (location.hostname !== 'm.v.qq.com') return; var AD_PATH = '/activity/downapp_activity.html'; var isAdUrl = function (u) { try { return typeof u === 'string' && u.indexOf(AD_PATH) !== -1; } catch (e) { return false; } }; // 当前正处在广告页(上一层拦截未生效的浏览器,如 Safari):立即弹回 if (location.pathname.indexOf(AD_PATH) !== -1) { var refHost = ''; try { refHost = new URL(document.referrer || '', location.href).hostname; } catch (e) {} var selfRef = refHost === 'm.v.qq.com' || /(^|\.)v\.qq\.com$/.test(refHost); if (location.search.indexOf('not_auto_open=1') !== -1 || selfRef) { try { if (history.length > 1) history.back(); else if (document.referrer) location.replace(document.referrer); else location.replace('https://m.v.qq.com/'); } catch (e) {} } return; } // Navigation API:拦截 location.href= / location.replace 等一切方式发起的广告页跳转 try { if (window.navigation && typeof window.navigation.addEventListener === 'function') { window.navigation.addEventListener('navigate', function (e) { try { var u = e.destination && e.destination.url; if (u && u.indexOf(AD_PATH) !== -1 && e.cancelable) e.preventDefault(); } catch (err) {} }); } } catch (err) {} // window.open 拦截 try { var _open = window.open; window.open = function (url) { if (isAdUrl(typeof url === 'string' ? url : '')) return null; return _open.apply(window, arguments); }; } catch (err) {} // 链接点击捕获拦截 try { document.addEventListener('click', function (e) { try { var t = e.target; var a = t && t.closest ? t.closest('a[href]') : null; if (a && isAdUrl(a.href)) { e.preventDefault(); e.stopPropagation(); } } catch (err) {} }, true); } catch (err) {} })(); // >>> QQ_AD_GUARD_END const HAS_GM = typeof GM !== 'undefined'; const NEW_GM = ((scope, GM) => { if (typeof GM_info === 'undefined' || GM_info.scriptHandler !== "Tampermonkey") return; try { if (compareVersions(GM_info.version, "5.3.2") < 0) return; } catch(e) { return; } const GM_xmlhttpRequestOrig = GM_xmlhttpRequest; const GM_xmlHttpRequestOrig = GM?.xmlHttpRequest; function compareVersions(v1, v2) { const parts1 = v1.split('.').map(Number); const parts2 = v2.split('.').map(Number); const length = Math.max(parts1.length, parts2.length); for (let i = 0; i < length; i++) { const num1 = parts1[i] || 0; const num2 = parts2[i] || 0; if (num1 > num2) return 1; if (num1 < num2) return -1; } return 0; } function GM_xmlhttpRequestWrapper(odetails) { if (odetails.redirect !== undefined) { return GM_xmlhttpRequestOrig(odetails); } const { onload, onloadend, onerror, onabort, ontimeout, ...details } = odetails; const _MAX_REDIRECTS = 5; const handleRedirects = (initialDetails, hop = 0) => { return GM_xmlhttpRequestOrig({ ...initialDetails, redirect: 'manual', onload: function(response) { if (response.status >= 300 && response.status < 400) { const m = response.responseHeaders.match(/Location:\s*(\S+)/i); const redirectUrl = m && m[1]; if (redirectUrl && hop < _MAX_REDIRECTS) { try { const absoluteUrl = new URL(redirectUrl, initialDetails.url).href; handleRedirects({ ...initialDetails, url: absoluteUrl }, hop + 1); return; } catch(e) {} } } if (onload) onload.call(this, response); if (onloadend) onloadend.call(this, response); }, onerror: function(response) { if (onerror) onerror.call(this, response); if (onloadend) onloadend.call(this, response); }, onabort: function(response) { if (onabort) onabort.call(this, response); if (onloadend) onloadend.call(this, response); }, ontimeout: function(response) { if (ontimeout) ontimeout.call(this, response); if (onloadend) onloadend.call(this, response); } }); }; return handleRedirects(details); } GM_xmlhttpRequest = GM_xmlhttpRequestWrapper; scope.GM_xmlhttpRequestOrig = GM_xmlhttpRequestOrig; if (GM?.xmlHttpRequest) { const gopd = Object.getOwnPropertyDescriptor(GM, 'xmlHttpRequest'); if (gopd && gopd.configurable === false) { return { __proto__: GM, xmlHttpRequest: GM_xmlHttpRequestWrapper, xmlHttpRequestOrig: GM_xmlHttpRequestOrig }; } else { GM.xmlHttpRequest = GM_xmlHttpRequestWrapper; GM.xmlHttpRequestOrig = GM_xmlHttpRequestOrig; } } return null; })(typeof window !== 'undefined' ? window : globalThis, HAS_GM ? GM : {}); if (HAS_GM && NEW_GM) GM = NEW_GM; const DNS_OPT = { _domainRank: new Map(), getLatency(domain) { const r = this._domainRank.get(domain); return r ? r.latency : Infinity; }, injectHints(domainList) { try { const frag = document.createDocumentFragment(); const dnsSelf = ['fastly.jsdelivr.net', 'cdn.jsdelivr.net', 'unpkg.com', 'gcore.jsdelivr.net']; [...new Set([...dnsSelf, ...domainList])].forEach(d => { const link = document.createElement('link'); link.rel = 'dns-prefetch'; link.href = '//' + d; frag.appendChild(link); }); if (document.head) document.head.appendChild(frag); } catch(e) {} }, boot(domainList) { this.injectHints(domainList); } }; const _UA_MOBILE = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); const isMobileView = () => _UA_MOBILE || window.innerWidth <= 768; const CONFIG = { API_TIMEOUT: 3500, STUCK_CHECK_TIMEOUT: 8000, SEARCH_CONCURRENCY: 16, FAST_EVAL_TIMEOUT: 700, SMART_SORTING: true, AUTOPLAY_NEXT_DELAY: 200, PANEL_LEAVE_CLOSE_DELAY: 1500, SPA_DEBOUNCE: 400, STORAGE_KEY_ICON_POSITION: 'vip_icon_pos_v9', VIDEO_URL_PATTERNS: [ /iqiyi\.com\/[vwa]_/, /iqiyi\.com\/play\//, /m\.iqiyi\.com\/(v|a|play|video)\//, /iq\.com\/play\//, /m\.iq\.com\/play\//, /youku\.com\/v_show\/id_/, /v\.youku\.com\/v_show\/id_/, /m\.youku\.com\/(v_show|video|play)\//, /youku\.com\/video\//, /youku\.com\/play\//, /v\.qq\.com\/(x\/cover|x\/page|tv|play)\//, /m\.v\.qq\.com\/(x\/cover|x\/page|tv|play)\//, /v\.qq\.com\/cover\//, /v\.qq\.com\/page\//, /m\.v\.qq\.com\/cover\//, /m\.v\.qq\.com\/page\//, /mgtv\.com\/(b|s|video)\//, /m\.mgtv\.com\/(b|s|video)\//, /bilibili\.com\/(video|bangumi\/play|anime|play)\//, /m\.bilibili\.com\/(video|bangumi\/play|anime|play)\//, /b23\.tv\//, /m\.b23\.tv\//, /le\.com\/ptv\/vplay\//, /m\.le\.com\/ptv\/vplay\//, /le\.com\/(play|video)\//, /m\.le\.com\/(play|video)\//, /tv\.sohu\.com\/v\//, /film\.sohu\.com\/album\//, /m\.sohu\.com\/(v|tv|film)\//, /sohu\.com\/play\//, /pptv\.com\/show\//, /m\.pptv\.com\/show\//, /pptv\.com\/play\//, /m\.pptv\.com\/play\//, /acfun\.cn\/v\/ac/, /m\.acfun\.cn\/v\/ac/, /acfun\.cn\/play\//, /m\.acfun\.cn\/play\//, /1905\.com\/play\//, /m\.1905\.com\/play\//, /1905\.com\/video\//, /m\.1905\.com\/video\//, /ixigua\.com\/(video|play)\//, /m\.ixigua\.com\/(video|play)\//, /douyin\.com\/video\//, /m\.douyin\.com\/video\//, /douyin\.com\/discover\//, /m\.douyin\.com\/discover\//, /kuaishou\.com\/(short-video|video|play)\//, /m\.kuaishou\.com\/(short-video|video|play)\//, /tudou\.com\/(listplay|albumplay|programs\/view|video)\//, /m\.tudou\.com\/(listplay|albumplay|programs\/view|video)\//, /fun\.tv\/(vod-play|player|play)\//, /funshion\.com\/(play|player)\//, /m\.fun\.tv\/(vod-play|player|play)\//, /baofeng\.com\/(play\/|play-|player\/)/, /bfeng\.cn\//, /m\.baofeng\.com\/(play\/|play-|player\/)/, /miguvideo\.com\/(detail|play|v|n|p)\//, /m\.miguvideo\.com\/(detail|play|v|n|p)\//, /cmvideo\.cn\/(detail|play|v|n|p)\//, /m\.cmvideo\.cn\/(detail|play|v|n|p)\//, /migumovie\.hcs\.cmvideo\.cn\/movie/, /stormsfy\.com\//, /hanju\.koudaibaobao\.com\//, /maiduidui\.com\/play\//, /rrsp\.tv\/play\//, /vas\.hiaiabc\.com\/play\// ], MESSAGES: { VIDEO_ENDED: 'tm_video_ended', PLAY_SUCCESS: 'tm_play_success', PLAY_ERROR: 'tm_play_error', STREAM_ALIVE: 'tm_stream_alive', LIB_CORRUPT: 'tm_lib_corrupt', PLAYER_READY: 'tm_player_ready', SWITCH_URL: 'tm_switch_url', SWITCH_ACK: 'tm_switch_ack', HIDE_CONTROLS: 'tm_hide_controls' }, SELECTORS: { PLAYER_ELEMENTS: [ '#tenvideo_player', '.txp_player_root', '#player-container', '#player', '[class*="txp_player"]', '[class*="mod_player"]', '.site-player', '#bilibili-player', '.bpx-player-container', '[class*="player-wrap"]', '.container-player', '#youku-player', '[class*="youku-player"]', '.iqp-player', '#iqp-player', '[class*="iqiyi-player"]', '#mgtv-player-wrap', '[class*="mgtv-player"]', '#sohuplayer', '#flashbox', '#le_player', '#player_swf', '#pp-player', '#ACPlayer', '#video-player', '#xigua-player', '.video-area', '.player-container', '.shaka-video-container', '#bf-player', '.bf-player', '#baofeng-player', '.bf-video-player', '#fun-player', '.fun-player', '#FunPlayer', '#h5player', '[class*="video-player"]', '[class*="videoPlayer"]', '[class*="play-container"]', '[class*="playContainer"]', '[id*="player"]', '[class*="player-box"]' ], QUICK_TITLE: ['meta[property="og:title"]', 'h1', '.video-title', '.title', '.vod_title', '.video-info-title'], PRECISE_TITLE: { 'iqiyi.com': '[class*="episodes_playingItem"] [class*="episodes_order"], .qy-episode-item[class*="is-active"] a, .album-list .is-active .title-content, [class*="selected"] .qy-episode-num, #text[style*="IQYHT-Bold"]', 'youku.com': '.box-anthology-item.active, .anthology-wrap li.active span, .anthology-item.current, .play-panel-item.active', 'v.qq.com': '.episode-item--select, .playlist-item--current, [class*="selected"] [class*="episode-item-text"], [class*="episode-item"][class*="selected"] .episode-item-text, [class*="episode-item"][class*="current"] .episode-item-text, [class*="episode-item"][class*="active"] .episode-item-text, [class*="numberListItem_select"] [class*="numberListItem_title"], [data-v-db0ab5fa].episode-item-text, [class*="episode"][class*="on"] [class*="text"], [class*="pick-list"] [class*="on"]', 'bilibili.com': '[class*="EpisodeVirtualList_numberTitle"], [class*="numberListItem_select"] [class*="numberListItem_title"], .ep-list-item.on .ep-item-title, [class*="episode_list"] [class*="selected"]', 'mgtv.com': '[class*="mgtv-player-aside-number-selector__number"], .episode-list .current a, .episode-series .current', 'sohu.com': 'li.pane-item.vip.on a, li.pane-item.on a, .player-album-list .on a', 'le.com': '.js-episode-item.on', 'pptv.com': '.episode-list .current', 'acfun.cn': '.active .title-wenzi', 'miguvideo.com': '[data-v-50548e8b].on span[data-v-50548e8b], [data-v-50548e8b].on, [class*="episodeTitle"][class*="on"]', 'baofeng.com': '.media-title, .player-album .on, .play-list .on, .episode-list .current, [class*="episode"][class*="active"], [class*="episode"][class*="on"]' }, PRECISE_MAIN_TITLE: { 'qq.com': '[data-mvp-identifier="intro"][title], .intro-title[title], .video-title[title], .player-title, [class*="video-title"], [class*="videoTitle"], [class*="mod_title"], h1[class*="title"]', 'v.qq.com': '[data-mvp-identifier="intro"][title], .intro-title[title], [class*="video-title"], [class*="videoTitle"], [class*="mod_title"], .player-title, h1[class*="title"], [class*="site-title"]', 'iqiyi.com': '[data-ai-entity="视频名称、主标题"], [data-ai-entity*="主标题"], [data-ai-entity*="视频名称"], [class*="meta_title"], [class*="meta_titleNotCloud"], [class*="meta_titleNewLabel"], [class*="episodeTitle"], .album-head-title', 'iq.com': '[data-ai-entity="视频名称、主标题"], [data-ai-entity*="主标题"], [data-ai-entity*="视频名称"], [class*="meta_title"]', 'youku.com': '[data-spm-anchor-id*="introduction"] .title, .title[style*="max-width"], .video-title, a[data-pb-txid="pg_playlist_title"][title]', 'bilibili.com': '[class*="mediaTitle"][title], [class*="mediaTitle"], .media-info-title-t', 'b23.tv': '[class*="mediaTitle"][title], [class*="mediaTitle"]', 'sohu.com': 'a[data-pb-txid="pg_playlist_title"][title]', 'mgtv.com': 'h2[class*="mgtv-player-aside-info__title"][title]', 'miguvideo.com': '[data-v-50548e8b][title].episodeTitle', 'le.com': '.j_jujiName, .juji_bar, h1.title, .detail-title, .video-title, [class*="movieName"], [class*="videoName"]', 'baofeng.com': '.media-title, .video-info h1, .player-title, .detail-title, .movie-title, h1.title, [class*="videoTitle"], [class*="video-title"]' }, MOBILE_TITLE_SELECTORS: { 'qq.com': '[data-mvp-identifier="intro"][title], .intro-title[title], [class*="video-title"], [class*="videoTitle"], [class*="mod_title"], h1', 'v.qq.com': '[data-mvp-identifier="intro"][title], .intro-title[title], [class*="video-title"], [class*="videoTitle"], [class*="mod_title"], h1', 'iqiyi.com': '[class*="title"], h1, .album-title, .video-title', 'youku.com': '[class*="title"], h1, .video-title, .show-title', 'bilibili.com': '[class*="title"], h1, .media-title, .video-title', 'mgtv.com': '[class*="title"], h1, .video-title', 'mgtv.com': '[class*="title"], h1, .video-title', 'sohu.com': '[class*="title"], h1, .video-title', 'le.com': '[class*="title"], h1, .video-title', 'douyin.com': '[class*="title"], h1, .video-title', 'kuaishou.com': '[class*="title"], h1, .video-title' } }, MOVIE_KEYWORDS: /^(HD|超清|高清|正片|国语|HD国语|720P|1080P|蓝光|4K|BD|TC|TS|DVD|抢先|高清版|HD高清|国语高清|HD中字)$/i, MOVIE_PRIORITY: ['蓝光', '4K', '1080P', '超清', 'HD国语', 'HD', '国语', '高清', '720P', 'BD', '正片', 'HD高清', '国语高清', 'HD中字', 'TC', 'TS', 'DVD', '抢先', '高清版'] }; const _MEDIA_EXT_RE = /\.m3u8|\.mp4|\.flv/i; const _TITLE_SPLIT_RE = /[-_\s((]/; const _EP_REMOVE_RE = /第.+[集季部]/; const _ROMAN_MAP = { 'Ⅰ': '1', 'Ⅱ': '2', 'Ⅲ': '3', 'Ⅳ': '4', 'Ⅴ': '5', 'Ⅵ': '6', 'Ⅶ': '7', 'Ⅷ': '8', 'Ⅸ': '9', 'Ⅹ': '10', 'Ⅺ': '11', 'Ⅻ': '12' }; const _ROMAN_RE = /[ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ]/g; const _NOISE_RE = /[\s\u200b-\u200f\ufeff_·、,,!!??::;;'"“”‘’\-–—\[\]【】()()]/g; const normalizeName = s => (s || '') .replace(/[\u200b-\u200f\ufeff]/g, '') .replace(_ROMAN_RE, c => _ROMAN_MAP[c] || c) .toLowerCase() .replace(_NOISE_RE, ''); const nameSimilarity = (a, b) => { const x = normalizeName(a), y = normalizeName(b); if (!x || !y) return 0; if (x === y) return 1; if (x.includes(y) || y.includes(x)) return 0.75 + 0.25 * Math.min(x.length, y.length) / Math.max(x.length, y.length); if (x.length < 2 || y.length < 2) return 0; const ga = new Set(), gb = new Set(); for (let i = 0; i < x.length - 1; i++) ga.add(x.slice(i, i + 2)); for (let i = 0; i < y.length - 1; i++) gb.add(y.slice(i, i + 2)); let inter = 0; ga.forEach(g => { if (gb.has(g)) inter++; }); return (2 * inter) / (ga.size + gb.size); }; const titleQueryVariants = title => { const out = []; const push = s => { s = (s || '').trim(); if (s && s.length > 1 && !out.includes(s)) out.push(s); }; const toArabic = s => s.replace(_ROMAN_RE, c => _ROMAN_MAP[c] || c); push(title); push(toArabic(title)); push(title.replace(/\s+/g, '')); const short = title.split(_TITLE_SPLIT_RE)[0]; push(short); push(toArabic(short)); return out; }; const _NUM_ONLY_RE = /^\d+$/; const _EP_PATTERN_RE = /(?:第|EP|Ep|ep|E)\s*(\d+)(?:集|话|期|部|季|章)?/i; const _EP_PREFIX_RE = /^(\d+)\s*(?:集|话|期|部|季|章)/; const _EP_SUFFIX_RE = /(\d+)\s*(?:集|话|期|部|季|章)(?:\D|$)/; const _EP_EP_RE = /(?:EP|Ep|ep)(\d+)/i; const _EP_SEASON_RE = /第\s*\d+\s*[季部]\s*第\s*(\d+)\s*[集话]/; const _EP_FALLBACK_RE = /(?:\D|^)(\d{1,4})(?:\D|$)/; const _CACHE_VERSION = 'v6'; const _CACHE_EXPIRY = 3600000; const SearchCache = { get(key) { try { const c = JSON.parse(GM_getValue('cache_' + _CACHE_VERSION + '_' + key, 'null')); if (c && Date.now() - c.ts < _CACHE_EXPIRY) return c.data; } catch (e) {} return null; }, set(key, data) { try { GM_setValue('cache_' + _CACHE_VERSION + '_' + key, JSON.stringify({ data: data, ts: Date.now() })); } catch (e) {} } }; function purgeSearchCache() { try { if (typeof GM_listValues !== 'function' || typeof GM_deleteValue !== 'function') return; const now = Date.now(); const prefix = 'cache_' + _CACHE_VERSION + '_'; GM_listValues().forEach(k => { if (k.indexOf('cache_') !== 0) return; if (k.indexOf(prefix) !== 0) { GM_deleteValue(k); return; } try { const c = JSON.parse(GM_getValue(k, 'null')); if (!c || now - c.ts >= _CACHE_EXPIRY) GM_deleteValue(k); } catch (e) { GM_deleteValue(k); } }); } catch (e) {} } const LibCache = { _cache: {}, _promises: {}, _ver: '4.7.11', _DEFS: { core: { key: 'vp_lib_shaka_core', meta: 'vp_lib_meta_shaka_core', marker: 'shaka', minLen: 200000, urls: [ 'https://fastly.jsdelivr.net/npm/shaka-player@4.7.11/dist/shaka-player.compiled.min.js', 'https://cdn.jsdelivr.net/npm/shaka-player@4.7.11/dist/shaka-player.compiled.min.js', 'https://gcore.jsdelivr.net/npm/shaka-player@4.7.11/dist/shaka-player.compiled.min.js', 'https://unpkg.com/shaka-player@4.7.11/dist/shaka-player.compiled.js' ] }, ui: { key: 'vp_lib_shaka_ui', meta: 'vp_lib_meta_shaka_ui', marker: 'shaka.ui', minLen: 100000, urls: [ 'https://fastly.jsdelivr.net/npm/shaka-player@4.7.11/dist/shaka-player.ui.js', 'https://cdn.jsdelivr.net/npm/shaka-player@4.7.11/dist/shaka-player.ui.js', 'https://gcore.jsdelivr.net/npm/shaka-player@4.7.11/dist/shaka-player.ui.js', 'https://unpkg.com/shaka-player@4.7.11/dist/shaka-player.ui.js' ] }, css: { key: 'vp_lib_shaka_css', meta: 'vp_lib_meta_shaka_css', marker: '.shaka-video-container', minLen: 8000, urls: [ 'https://fastly.jsdelivr.net/npm/shaka-player@4.7.11/dist/controls.css', 'https://cdn.jsdelivr.net/npm/shaka-player@4.7.11/dist/controls.css', 'https://gcore.jsdelivr.net/npm/shaka-player@4.7.11/dist/controls.css', 'https://unpkg.com/shaka-player@4.7.11/dist/controls.css' ] } }, _sum(str) { let h = 0x811c9dc5; for (let i = 0; i < str.length; i++) { h ^= str.charCodeAt(i); h = (h + ((h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24))) >>> 0; } return h.toString(36); }, _valid(kind, code, meta) { const def = this._DEFS[kind]; if (!meta || typeof code !== 'string') return false; if (meta.v !== this._ver) return false; if (code.length < def.minLen || meta.len !== code.length) return false; if (meta.sum !== this._sum(code)) return false; return code.indexOf(def.marker) !== -1; }, _read(kind) { try { const code = GM_getValue(this._DEFS[kind].key, ''); if (!code) return null; let meta = null; try { meta = JSON.parse(GM_getValue(this._DEFS[kind].meta, 'null')); } catch (e) {} if (this._valid(kind, code, meta)) return code; } catch (e) {} this._clearKind(kind); return null; }, _write(kind, code) { try { GM_setValue(this._DEFS[kind].key, code); GM_setValue(this._DEFS[kind].meta, JSON.stringify({ v: this._ver, len: code.length, sum: this._sum(code), ts: Date.now() })); } catch (e) { console.warn('[VIP] Persist player lib failed:', e && e.message); } }, _clearKind(kind) { try { GM_setValue(this._DEFS[kind].key, ''); GM_setValue(this._DEFS[kind].meta, ''); } catch (e) {} }, purge() { Object.keys(this._DEFS).forEach(kind => { this._cache[kind] = null; this._promises[kind] = null; this._clearKind(kind); }); }, _metaOk(kind) { try { const meta = JSON.parse(GM_getValue(this._DEFS[kind].meta, 'null')); return !!(meta && meta.v === this._ver && meta.len > this._DEFS[kind].minLen); } catch (e) { return false; } }, _fetchSingle(url, timeout = 4000) { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: 'GET', url: url, timeout: timeout, onload(r) { if (r.status >= 200 && r.status < 400 && r.responseText) { resolve(r.responseText); } else { reject(new Error('HTTP ' + r.status)); } }, onerror() { reject(new Error('Network error')); }, ontimeout() { reject(new Error('Timeout')); } }); }); }, _fetchWithFallback(kind) { const def = this._DEFS[kind]; const urls = def.urls; const marker = def.marker; const minLen = def.minLen; return new Promise((resolve) => { let index = 0; const tryNext = () => { if (index >= urls.length) { resolve(null); return; } const url = urls[index]; this._fetchSingle(url, 4000) .then(code => { if (code && code.length >= minLen && code.indexOf(marker) !== -1) { resolve(code); } else { index++; tryNext(); } }) .catch(() => { index++; tryNext(); }); }; tryNext(); }); }, async _load(kind) { const cached = this._read(kind); if (cached) return cached; const code = await this._fetchWithFallback(kind); if (code) this._write(kind, code); return code; }, preload() { if (Object.keys(this._DEFS).every(kind => this._metaOk(kind))) return; this.getCore(); this.getUi(); this.getCss(); }, async get(kind) { if (this._cache[kind]) return this._cache[kind]; if (this._promises[kind]) return await this._promises[kind]; this._promises[kind] = this._load(kind).then(code => { if (code) this._cache[kind] = code; else this._promises[kind] = null; // 加载失败不缓存空结果,允许后续重试 return code; }); return await this._promises[kind]; }, getCore() { return this.get('core'); }, getUi() { return this.get('ui'); }, getCss() { return this.get('css'); } }; LibCache.preload(); const ApiStats = { _p: {}, _t: null, _priority: new Set(['西瓜', 'iqiyi', '新浪', '360', '1080', '天堂', '新浪', '速播2', 'U酷', '红牛', '百度']), _flush() { const p = this._p; this._p = {}; this._t = null; for (const [k, v] of Object.entries(p)) GM_setValue(`api_stats_${k}`, v); }, _schedule() { if (!this._t) this._t = setTimeout(() => this._flush(), 2000); }, get(n) { return this._p[n] || GM_getValue(`api_stats_${n}`) || { s: 0, f: 0, l: 0, r: 0 }; }, ok(n, lat) { const s = this.get(n); s.s++; s.l += lat; s.r++; this._p[n] = s; this._schedule(); }, fail(n) { const s = this.get(n); s.f++; s.r++; this._p[n] = s; this._schedule(); }, score(s, name) { if (name && this._priority.has(name)) return 99999; if (s.r < 3) return 1000; const sr = s.s / s.r; if (sr < 0.5) return -1000; return sr * 10000 - (s.s ? s.l / s.s : CONFIG.API_TIMEOUT); } }; const RAW_APIS = [ { n: "1080", u: atob("aHR0cHM6Ly9hcGkuMTA4MHp5a3UuY29tL2luYy9hcGlqc29uLnBocC9wcm92aWRlL3ZvZC8=") }, { n: "iqiyi", u: atob("aHR0cHM6Ly9pcWl5aXp5YXBpLmNvbS9hcGkucGhwL3Byb3ZpZGUvdm9kLw==") }, { n: "360", u: atob("aHR0cHM6Ly8zNjB6eS5jb20vYXBpLnBocC9wcm92aWRlL3ZvZC8=") }, { n: "西瓜", u: atob("aHR0cHM6Ly9jYWlqaS54Z3p5YXBpLmNvbS9hcGkucGhwL3Byb3ZpZGUvdm9kLw==") }, { n: "艾旦", u: atob("aHR0cDovL3d3dy5sb3ZlZGFuLm5ldC9hcGkucGhwL3Byb3ZpZGUvdm9kLw==") }, { n: "百度", u: atob("aHR0cDovL2FwaS5hcGliZHp5LmNvbS9hcGkucGhwL3Byb3ZpZGUvdm9kLw==") }, { n: "蛋蛋", u: atob("aHR0cDovL2RkbWYubmV0L2FwaS5waHAvcHJvdmlkZS92b2Qv") }, { n: "非凡", u: atob("aHR0cHM6Ly9hcGkuZmZ6eWFwaS5jb20vYXBpLnBocC9wcm92aWRlL3ZvZC8=") }, { n: "非凡2", u: atob("aHR0cDovL2NqLmZmenlhcGkuY29tL2FwaS5waHAvcHJvdmlkZS92b2Qv") }, { n: "光速", u: atob("aHR0cHM6Ly9hcGkuZ3VhbmdzdWFwaS5jb20vYXBpLnBocC9wcm92aWRlL3ZvZC8=") }, { n: "豪华", u: atob("aHR0cHM6Ly9oaHp5YXBpLmNvbS9hcGkucGhwL3Byb3ZpZGUvdm9kLw==") }, { n: "红牛", u: atob("aHR0cHM6Ly93d3cuaG9uZ25pdXp5Mi5jb20vYXBpLnBocC9wcm92aWRlL3ZvZC8=") }, { n: "虎牙", u: atob("aHR0cHM6Ly93d3cuaHV5YWFwaS5jb20vYXBpLnBocC9wcm92aWRlL3ZvZC8=") }, { n: "极速", u: atob("aHR0cHM6Ly9qc3p5YXBpLmNvbS9hcGkucGhwL3Byb3ZpZGUvdm9kLw==") }, { n: "巨量", u: atob("aHR0cHM6Ly9hcGkuanVsaWFuZy5saXZlL2FwaS9wcm92aWRlL3ZvZC8=") }, { n: "猫眼", u: atob("aHR0cHM6Ly9hcGkubWFveWFuYXBpLnRvcC9hcGkucGhwL3Byb3ZpZGUvdm9kLw==") }, { n: "魔都", u: atob("aHR0cHM6Ly9jYWlqaS5tb2R1YXBpLmNjL2FwaS5waHAvcHJvdmlkZS92b2Qv") }, { n: "魔都2", u: atob("aHR0cHM6Ly93d3cubWR6eWFwaS5jb20vYXBpLnBocC9wcm92aWRlL3ZvZC8=") }, { n: "量子", u: atob("aHR0cHM6Ly9jai5semlhcGkuY29tL2FwaS5waHAvcHJvdmlkZS92b2Qv") }, { n: "如意", u: atob("aHR0cDovL2NqLnJ5Y2phcGkuY29tL2FwaS5waHAvcHJvdmlkZS92b2Qv") }, { n: "天堂", u: atob("aHR0cHM6Ly9jYWlqaS5keXR0enlhcGkuY29tL2FwaS5waHAvcHJvdmlkZS92b2Qv") }, { n: "天堂2", u: atob("aHR0cDovL2NhaWppLmR5dHR6eWFwaS5jb20vYXBpLnBocC9wcm92aWRlL3ZvZC8=") }, { n: "无忧", u: atob("aHR0cHM6Ly93d3cud3l2b2QuY29tL2FwaS5waHAvcHJvdmlkZS92b2Qv") }, { n: "无尽", u: atob("aHR0cHM6Ly9hcGkud3VqaW5hcGkubWUvYXBpLnBocC9wcm92aWRlL3ZvZC8=") }, { n: "新浪", u: atob("aHR0cHM6Ly9hcGkueGlubGFuZ2FwaS5jb20veGlubGFuZ2FwaS5waHAvcHJvdmlkZS92b2Qv") }, { n: "一零", u: atob("aHR0cDovL2FwaS4xMDgwenlrdS5jb20vaW5jL2FwaV9tYWMxMC5waHAvcHJvdmlkZS92b2Qv") }, { n: "ikun", u: atob("aHR0cHM6Ly9pa3VuenlhcGkuY29tL2FwaS5waHAvcHJvdmlkZS92b2Qv") }, { n: "U酷", u: atob("aHR0cHM6Ly9hcGkudWt1YXBpLmNvbS9hcGkucGhwL3Byb3ZpZGUvdm9kLw==") }, { n: "优质", u: atob("aHR0cHM6Ly9hcGkueXp6eS1hcGkuY29tL2luYy9hcGlqc29uLnBocC9wcm92aWRlL3ZvZC8=") }, { n: "天涯", u: atob("aHR0cHM6Ly90eXlzenkuY29tL2FwaS5waHAvcHJvdmlkZS92b2Q=") }, { n: "量子2", u: atob("aHR0cHM6Ly9jai5semNhaWppLmNvbS9hcGkucGhwL3Byb3ZpZGUvdm9k") }, { n: "CK", u: atob("aHR0cHM6Ly9ja3p5Lm1lL2FwaS5waHAvcHJvdmlkZS92b2Q=") }, { n: "索尼", u: atob("aHR0cHM6Ly9zdW9uaWFwaS5jb20vYXBpLnBocC9wcm92aWRlL3ZvZA==") }, { n: "最大2", u: atob("aHR0cHM6Ly96dWlkYXp5Lm1lL2FwaS5waHAvcHJvdmlkZS92b2Q=") }, { n: "暴风", u: atob("aHR0cHM6Ly9iZnp5YXBpLmNvbS9hcGkucGhwL3Byb3ZpZGUvdm9k") }, { n: "无尽2", u: atob("aHR0cHM6Ly9hcGkud3VqaW5hcGkuY29tL2FwaS5waHAvcHJvdmlkZS92b2Q=") }, { n: "速播", u: atob("aHR0cHM6Ly9zdWJvY2FpamkuY29tL2FwaS5waHAvcHJvdmlkZS92b2Q=") }, { n: "金鹰", u: atob("aHR0cHM6Ly9qaW55aW5nenkuY29tL2FwaS5waHAvcHJvdmlkZS92b2Q=") }, ]; const _PRIORITY_ORDER = ['西瓜', 'iqiyi', '新浪', '360', '1080', '天堂', '新浪', '速播2', 'U酷', '红牛', '百度']; const _LOW_PRIORITY = new Set(['量子', '量子2', '最大2']); const processApis = raw => { const m = new Map(); raw.forEach(a => { if (!m.has(a.u)) m.set(a.u, { name: a.n, url: a.u, shortName: a.n }); }); const apis = Array.from(m.values()); const priority = apis.filter(a => ApiStats._priority.has(a.shortName)); priority.sort((a, b) => { const ai = _PRIORITY_ORDER.indexOf(a.shortName); const bi = _PRIORITY_ORDER.indexOf(b.shortName); return (ai === -1 ? 999 : ai) - (bi === -1 ? 999 : bi); }); const low = apis.filter(a => _LOW_PRIORITY.has(a.shortName)); const others = apis.filter(a => !ApiStats._priority.has(a.shortName) && !_LOW_PRIORITY.has(a.shortName)); if (CONFIG.SMART_SORTING) { others.sort((a, b) => ApiStats.score(ApiStats.get(b.shortName), b.shortName) - ApiStats.score(ApiStats.get(a.shortName), a.shortName)); } return [...priority, ...others, ...low]; }; const UNIQUE_APIS = processApis(RAW_APIS); const State = { eps: [], curUrl: '', hiddenEl: null, panelOpen: false, curURL: location.href, dom: {}, timers: {}, cache: { key: null, results: [] }, activeName: null, firstAuto: false, curEp: null, failed: new Set(), failedSources: new Set(), closed: false, searchId: 0, playing: false, switchCount: 0, stuckPending: false, isPageLoad: true, lastSwitchTime: 0, isAutoSwitch: false, playGeneration: 0, libReloadTried: false, lastPlayUrl: '', iframeReady: false, switchAckGen: 0, prewarmStarted: false }; const EP_MATCH_PATTERNS = [ { regex: /第\s*(\d+)\s*集/, group: 1 }, { regex: /第\s*(\d+)\s*话/, group: 1 }, { regex: /第\s*(\d+)\s*期/, group: 1 }, { regex: /EP\s*(\d+)/i, group: 1 }, { regex: /Ep\s*(\d+)/, group: 1 }, { regex: /ep\s*(\d+)/, group: 1 }, { regex: /E(\d+)/i, group: 1 }, { regex: /(\d+)\s*集/, group: 1 }, { regex: /(\d+)\s*话/, group: 1 }, { regex: /(\d+)\s*期/, group: 1 }, { regex: /\[(\d+)\]/, group: 1 }, { regex: /【(\d+)】/, group: 1 }, { regex: /((\d+))/, group: 1 }, { regex: /\((\d+)\)/, group: 1 } ]; function matchEpisodeEnhanced(epName, targetNum) { if (!epName || !targetNum) return false; const cleanName = epName.trim(); const num = parseInt(targetNum, 10); if (/^\d+$/.test(cleanName) && parseInt(cleanName, 10) === num) return true; for (const pattern of EP_MATCH_PATTERNS) { const match = cleanName.match(pattern.regex); if (match && match[pattern.group]) { if (parseInt(match[pattern.group], 10) === num) return true; } } if (cleanName.includes(targetNum)) { const idx = cleanName.indexOf(targetNum); const before = idx === 0 ? '' : cleanName.charAt(idx - 1); const after = idx + targetNum.length >= cleanName.length ? '' : cleanName.charAt(idx + targetNum.length); if ((/\D/.test(before) || idx === 0) && (/\D/.test(after) || idx + targetNum.length === cleanName.length)) { return true; } } return false; } const VIDEO_DOMAINS = [ 'iqiyi.com', 'iq.com', 'youku.com', 'v.qq.com', 'm.v.qq.com', 'mgtv.com', 'bilibili.com', 'b23.tv', 'le.com', 'letv.com', 'sohu.com', 'pptv.com', 'acfun.cn', '1905.com', 'ixigua.com', 'douyin.com', 'kuaishou.com', 'miguvideo.com', 'cmvideo.cn', 'baofeng.com', 'fun.tv', 'funshion.com', 'bfeng.cn', 'stormsfy.com', 'tudou.com', 'hanju.koudaibaobao.com', 'maiduidui.com', 'rrsp.tv', 'vas.hiaiabc.com', 'mgtv.com' ]; const VIDEO_URL_KEYWORDS = [ '/video/', '/play/', '/v_show/', '/v_play/', '/episode/', '/bangumi/', '/show/', '/detail/', '/movie/', '/tv/', '/film/', '/anime/', '/variety/', '/documentary/', '/x/cover/', '/x/page/', '/x/web-interface/' ]; const VIDEO_PLAYER_SELECTORS = [ 'video', 'iframe[src*="player"]', 'iframe[src*="video"]', '[class*="player"]', '[id*="player"]', '[class*="video"]', '[id*="video"]', '.shaka-video-container', '#shaka-player-container', '.xgplayer', '.dplayer', '.video-player', '[class*="migu-player"]', '[class*="commonPlayer"]', '#wPlayer', '#player-container', '#sohuplayer', '#flashbox', '.iqp-player', '#bilibili-player', '.bpx-player-container', '#mgtv-player-wrap', '#le_player', '#player_swf', '#pp-player', '#ACPlayer', '#video-player', '#xigua-player', '.video-area', '.player-container', '#bf-player', '.bf-player', '#baofeng-player', '.bf-video-player', '#fun-player', '.fun-player', '#FunPlayer', '#h5player', '[class*="txp_player"]', '[class*="tenvideo"]', '[class*="yvp-player"]', '[class*="youku-player"]', '[class*="iqiyi-player"]', '[class*="le-player"]', '[class*="sohu-player"]', '[class*="pptv-player"]', '[class*="ac-player"]', '[class*="mgtv-player"]' ]; const EXACT_PLAYER_SELECTORS = [ '#tenvideo_player', '.txp_player_root', '#player-container', '#player', '[class*="txp_player"]', '[class*="mod_player"]', '.site-player', '#bilibili-player', '.bpx-player-container', '[class*="player-wrap"]', '.container-player', '#youku-player', '[class*="youku-player"]', '.iqp-player', '#iqp-player', '[class*="iqiyi-player"]', '#mgtv-player-wrap', '[class*="mgtv-player"]', '#sohuplayer', '#flashbox', '#le_player', '#player_swf', '#pp-player', '#ACPlayer', '#video-player', '#xigua-player', '.video-area', '.shaka-video-container', '#bf-player', '.bf-player', '#baofeng-player', '#fun-player', '.fun-player', '#FunPlayer', '#h5player' ]; const _EXACT_PLAYER_SEL = EXACT_PLAYER_SELECTORS.join(', '); const onVideoPage = (() => { let _cache = { url: '', result: false, ts: 0 }; return () => { const href = location.href; if (href === _cache.url && Date.now() - _cache.ts < 500) return _cache.result; const hn = location.hostname; const isMobile = isMobileView(); let _result; if (isMobile) { if (CONFIG.VIDEO_URL_PATTERNS.some(p => p.test(href))) { _cache = { url: href, result: true, ts: Date.now() }; return true; } if (VIDEO_URL_KEYWORDS.some(kw => href.toLowerCase().includes(kw))) { if (VIDEO_DOMAINS.some(d => hn.includes(d))) { _cache = { url: href, result: true, ts: Date.now() }; return true; } } if (VIDEO_DOMAINS.some(d => hn.includes(d))) { if (document.querySelector('video')) { _cache = { url: href, result: true, ts: Date.now() }; return true; } if (document.querySelector(_EXACT_PLAYER_SEL)) { _cache = { url: href, result: true, ts: Date.now() }; return true; } const title = document.title.toLowerCase(); if (title.includes('播放') || title.includes('play') || title.includes('watch')) { _cache = { url: href, result: true, ts: Date.now() }; return true; } } _cache = { url: href, result: false, ts: Date.now() }; return false; } const isVideoSite = VIDEO_DOMAINS.some(d => hn.includes(d)); if (!isVideoSite) { _cache = { url: href, result: false, ts: Date.now() }; return false; } const hasVideoUrl = CONFIG.VIDEO_URL_PATTERNS.some(p => p.test(href)) || VIDEO_URL_KEYWORDS.some(kw => href.toLowerCase().includes(kw)); if (!hasVideoUrl) { _cache = { url: href, result: false, ts: Date.now() }; return false; } const hasVideo = document.querySelector('video'); const hasPlayer = !!document.querySelector(_EXACT_PLAYER_SEL); if (hasVideo || hasPlayer) { _cache = { url: href, result: true, ts: Date.now() }; return true; } if (document.querySelector('video[src], video source[src]')) { _cache = { url: href, result: true, ts: Date.now() }; return true; } _cache = { url: href, result: false, ts: Date.now() }; return false; }; })(); const UI = { init() { const existingRoot = document.getElementById('vip-root'); if (existingRoot) existingRoot.remove(); const staleOv = document.getElementById('vip-overlay'); if (staleOv) staleOv.remove(); const staleToast = document.getElementById('vip-toast'); if (staleToast) staleToast.remove(); this._css(); State.dom.c = this._el('div', { id: 'vip-root' }); State.dom.btn = this._el('div', { id: 'vip-btn', title: '点击展开/解析VIP视频 (可拖拽)' }); State.dom.btn.innerHTML = '