// ==UserScript== // @name AI视频解析 - 全网VIP视频免费看 // @namespace https://workbuddy.cn/ // @version 1.2.0 // @description 在爱奇艺/腾讯视频/优酷/芒果TV/B站/搜狐/1905/PP视频等页面注入解析面板,一键调用解析接口免费观看VIP视频。支持当前集数自动识别、解析失败自动换线重试、下载当前集(接AIX)、复制含集数的解析地址、多线路切换、自定义线路、记忆上次选择、弹窗播放。仅用于学习交流。 // @author WorkBuddy // @match *://*.iqiyi.com/* // @match *://*.qiyi.com/* // @match *://v.qq.com/* // @match *://*.tencent.com/* // @match *://*.youku.com/* // @match *://*.tudou.com/* // @match *://*.mgtv.com/* // @match *://*.bilibili.com/* // @match *://*.b23.tv/* // @match *://*.sohu.com/* // @match *://*.1905.com/* // @match *://*.le.com/* // @match *://*.pptv.com/* // @match *://*.wasu.cn/* // @match *://*.acfun.cn/* // @grant GM_setValue // @grant GM_getValue // @grant GM_addStyle // @run-at document-idle // @license MIT // ==/UserScript== (function () { 'use strict'; /* ====== 默认解析线路(取自全民解析网,并补充常用稳定接口) ====== encode: true -> 接口后面拼 encodeURIComponent(视频地址) encode: false -> 接口后面直接拼原始视频地址 不同接口约定不同,失败时切换线路或改编码方式即可。 */ var DEFAULT_LINES = [ { name: 'im1907(默认)', url: 'https://im1907.top?jx=', encode: false }, { name: '推荐线路 xymp4', url: 'https://jx.xymp4.cc/?url=', encode: true }, { name: '线路1 2s0', url: 'https://jx.2s0.cn/player/?url=', encode: true }, { name: '线路2 xmflv', url: 'https://jx.xmflv.com/?url=', encode: true }, { name: '线路3 789jiexi', url: 'https://jx.789jiexi.com/?url=', encode: true }, { name: '线路4 hls.one', url: 'https://jx.hls.one/?url=', encode: true }, { name: '线路5 txnp', url: 'https://bfq.txnp.cn/player?url=', encode: true }, { name: '线路6 fongmi', url: 'https://json.fongmi.cc/web?url=', encode: true } ]; /* ---------- 存储工具 ---------- */ function loadLines() { var ls = GM_getValue('ai_lines', null); if (!ls || !ls.length) { ls = DEFAULT_LINES.slice(); GM_setValue('ai_lines', ls); } return ls; } function saveLines(ls) { GM_setValue('ai_lines', ls); } var lines = loadLines(); var curIdx = GM_getValue('ai_line_idx', 0); if (curIdx >= lines.length) curIdx = 0; var encodeUrl = GM_getValue('ai_encode', true); var autoSwitch = GM_getValue('ai_autoswitch', true); // 解析失败自动换线 var aixUrl = GM_getValue('ai_aix_url', ''); // AIX 下载入口模板,含 {url} var panelOpen = false, modalOpen = false; // 自动换线看门狗参数(跨域无法读取播放状态,均为超时启发式兜底) var LOAD_TIMEOUT = 12000; // 线路页面加载超时 -> 视作该线路失效 var WATCHDOG = 15000; // 页面已加载但超过该时间仍未播放 -> 视作解析失败 var retryActive = false; var triedSet = []; var loadTimer = null, watchTimer = null; /* ---------- 样式 ---------- */ GM_addStyle([ '#ai-jx-btn{position:fixed;right:18px;bottom:18px;z-index:2147483647;', 'background:linear-gradient(135deg,#ff5f6d,#ffc371);color:#fff;border:none;', 'padding:10px 16px;border-radius:24px;font-size:14px;font-weight:bold;cursor:pointer;', 'box-shadow:0 4px 14px rgba(0,0,0,.3);font-family:-apple-system,"Microsoft YaHei",sans-serif;}', '#ai-jx-panel{position:fixed;right:18px;bottom:70px;z-index:2147483647;width:340px;', 'background:#fff;border-radius:12px;box-shadow:0 8px 30px rgba(0,0,0,.25);', 'font-family:-apple-system,"Microsoft YaHei",sans-serif;overflow:hidden;display:none;}', '#ai-jx-panel .hd{background:linear-gradient(135deg,#ff5f6d,#ffc371);color:#fff;', 'padding:10px 14px;font-weight:bold;font-size:15px;display:flex;justify-content:space-between;align-items:center;}', '#ai-jx-panel .hd .x{cursor:pointer;font-size:18px;line-height:1;}', '#ai-jx-panel .bd{padding:12px 14px;}', '#ai-jx-panel input,#ai-jx-panel select{width:100%;box-sizing:border-box;', 'padding:8px 10px;margin-bottom:10px;border:1px solid #ddd;border-radius:8px;font-size:13px;}', '#ai-jx-panel .row{display:flex;gap:8px;margin-bottom:10px;}', '#ai-jx-panel .row button{flex:1;border:none;border-radius:8px;padding:9px 0;font-size:13px;', 'font-weight:bold;cursor:pointer;color:#fff;}', '#ai-jx-panel .b-play{background:#ff5f6d;}#ai-jx-panel .b-new{background:#4a90e2;}', '#ai-jx-panel .b-copy{background:#7e57c2;}#ai-jx-panel .b-mgr{background:#555;}', '#ai-jx-panel .b-raw{background:#26a69a;}', '#ai-jx-panel .opt{font-size:12px;color:#666;display:flex;align-items:center;gap:6px;margin-bottom:8px;}', '#ai-jx-panel .ep{font-size:12px;color:#2e7d32;margin:-4px 0 8px;min-height:14px;}', '#ai-jx-panel .mgr{display:none;border-top:1px dashed #eee;padding-top:10px;margin-top:4px;}', '#ai-jx-panel .mgr .row button{background:#2e7d32;}', '#ai-jx-panel .tip{font-size:12px;color:#999;min-height:16px;margin-top:4px;}', '#ai-jx-mask{position:fixed;inset:0;z-index:2147483646;background:rgba(0,0,0,.85);display:none;}', '#ai-jx-mask .bar{position:absolute;top:0;left:0;right:0;background:#111;color:#fff;', 'display:flex;align-items:center;gap:8px;padding:8px 12px;flex-wrap:wrap;font-family:-apple-system,"Microsoft YaHei",sans-serif;}', '#ai-jx-mask .bar select{flex:1;min-width:120px;padding:6px 8px;border-radius:6px;border:none;}', '#ai-jx-mask .bar button{background:#ff5f6d;color:#fff;border:none;border-radius:6px;padding:6px 10px;cursor:pointer;font-size:13px;}', '#ai-jx-mask .bar button.b-retry{background:#4a90e2;}', '#ai-jx-mask .bar button.b-dl{background:#2e7d32;}', '#ai-jx-mask iframe{position:absolute;top:52px;left:0;right:0;bottom:0;width:100%;height:calc(100% - 52px);border:0;background:#000;}' ].join('')); /* ---------- 浮窗按钮 ---------- */ var btn = document.createElement('button'); btn.id = 'ai-jx-btn'; btn.textContent = 'AI视频解析'; document.body.appendChild(btn); /* ---------- 主面板 ---------- */ var panel = document.createElement('div'); panel.id = 'ai-jx-panel'; panel.innerHTML = '
AI视频解析×
' + '
' + '' + '
' + '' + '
' + '' + '' + '
' + '
' + '' + '' + '
' + '' + '' + '' + '
' + '' + '' + '
' + '
提示:删除请在下方列表点“删”。
' + '' + '
' + '
' + '' + '
' + '
' + '
' + '
'; document.body.appendChild(panel); panel.querySelector('#ai-aix').value = aixUrl; /* ---------- 弹窗播放 ---------- */ var mask = document.createElement('div'); mask.id = 'ai-jx-mask'; mask.innerHTML = '
' + '' + '' + '' + '' + '' + '
' + ''; document.body.appendChild(mask); var mIframe = mask.querySelector('#ai-m-iframe'); /* ---------- 渲染线路下拉 ---------- */ function renderLines() { var sel = panel.querySelector('#ai-line'); sel.innerHTML = ''; lines.forEach(function (l, i) { var o = document.createElement('option'); o.value = i; o.textContent = l.name; if (i === curIdx) o.selected = true; sel.appendChild(o); }); var msel = mask.querySelector('#ai-m-line'); msel.innerHTML = ''; lines.forEach(function (l, i) { var o = document.createElement('option'); o.value = i; o.textContent = l.name; if (i === curIdx) o.selected = true; msel.appendChild(o); }); var all = panel.querySelector('#ai-all'); all.innerHTML = ''; lines.forEach(function (l, i) { var o = document.createElement('option'); o.value = i; o.textContent = (i + 1) + '. ' + l.name + ' [' + (l.encode ? '编码' : '原始') + ']'; all.appendChild(o); }); } renderLines(); /* ---------- 当前视频地址(含集数自动识别) ---------- */ function cleanParams(u) { try { var url = new URL(u); ['_t', 'sharefrom', 't', 'from', 'scene', 'spm'].forEach(function (k) { url.searchParams.delete(k); }); return url.toString(); } catch (e) { return u; } } // 按平台识别“当前集”,返回 {url, info} function detectVideoUrl() { var host = location.hostname; var u = location.href; var info = ''; // ---------- B站 ---------- if (host.indexOf('bilibili.com') > -1) { // 番剧/国创单集页:ep 已唯一标识,直接用 if (/\/bangumi\/play\/ep\d+/i.test(u)) { return { url: cleanParams(u), info: 'B站番剧·单集' }; } if (/\/video\//i.test(u)) { var p = 1; var m = u.match(/[?&]p=(\d+)/); if (m) { p = parseInt(m[1], 10); } else { // 多P:取当前选中的分P var active = document.querySelector('.list-box__item.on, .video-pod__item.on, .list-box__item.cur'); if (active) { var dp = active.getAttribute('data-page'); if (dp) { p = parseInt(dp, 10) || p; } else if (active.parentNode) { var sibs = active.parentNode.children; for (var i = 0; i < sibs.length; i++) { if (sibs[i] === active) { p = i + 1; break; } } } } } try { var bu = new URL(u); bu.searchParams.set('p', p); u = bu.toString(); } catch (e) { u = u + (u.indexOf('?') > -1 ? '&' : '?') + 'p=' + p; } return { url: u, info: 'B站视频·第' + p + 'P' }; } } // ---------- 腾讯视频 ---------- if (host.indexOf('v.qq.com') > -1 || host.indexOf('tencent.com') > -1) { var vm = u.match(/[?&]vid=([^&]+)/); if (vm) { return { url: cleanParams(u), info: '腾讯视频·指定VID' }; } // 从播放列表取当前集 vid var item = document.querySelector( '#playList .item.on, .playlist__item--active, #playlist li.cur, .video_list li.on, ' + '[class*="playlist"] li[class*="on"], [class*="playlist"] li[class*="cur"]' ); if (item) { var vid = item.getAttribute('data-vid') || ''; if (!vid) { var a = item.querySelector('a'); var href = a ? (a.getAttribute('href') || '') : (item.getAttribute('data-url') || ''); var mm = href.match(/vid=([^&]+)/) || href.match(/cover\/[^/]+\/([^.?]+)/); if (mm) vid = mm[1]; } if (vid) { try { var tu = new URL(u); tu.searchParams.set('vid', vid); u = tu.toString(); } catch (e) { u = u + (u.indexOf('?') > -1 ? '&' : '?') + 'vid=' + vid; } return { url: u, info: '腾讯视频·当前集' }; } } return { url: cleanParams(u), info: '腾讯视频·封面页' }; } // ---------- 其他平台:直接用当前地址 ---------- return { url: cleanParams(u), info: '' }; } function refreshUrl() { var d = detectVideoUrl(); panel.querySelector('#ai-url').value = d.url; panel.querySelector('#ai-ep').textContent = d.info ? ('已识别:' + d.info) : ''; } refreshUrl(); /* ---------- 复制工具 ---------- */ function doCopy(text) { var ta = document.createElement('textarea'); ta.value = text; document.body.appendChild(ta); ta.select(); var ok = false; try { ok = document.execCommand('copy'); } catch (e) { ok = false; } document.body.removeChild(ta); return ok; } /* ---------- 构造解析地址 ---------- */ function buildLink(idx, rawUrl) { var l = lines[idx]; var u = (rawUrl != null) ? rawUrl : panel.querySelector('#ai-url').value.trim(); if (!u) { tip('请先填入视频地址'); return null; } var enc = (typeof l.encode === 'boolean') ? l.encode : encodeUrl; return l.url + (enc ? encodeURIComponent(u) : u); } function tip(msg) { panel.querySelector('#ai-tip').textContent = msg || ''; } /* ---------- 线路切换 / 弹窗注入 ---------- */ function applyLine(idx) { curIdx = idx; panel.querySelector('#ai-line').value = idx; mask.querySelector('#ai-m-line').value = idx; GM_setValue('ai_line_idx', idx); } function setIframe(idx) { applyLine(idx); if (modalOpen) { var link = buildLink(idx); if (link) mIframe.src = link; } } /* ---------- 自动换线重试 ---------- */ function clearRetryTimers() { if (loadTimer) { clearTimeout(loadTimer); loadTimer = null; } if (watchTimer) { clearTimeout(watchTimer); watchTimer = null; } } function stopRetry() { retryActive = false; triedSet = []; clearRetryTimers(); } function nextUntried(from) { for (var i = 0; i < lines.length; i++) { var c = (from + i + 1) % lines.length; if (triedSet.indexOf(c) === -1) return c; } return -1; } function startRetryFrom(idx) { retryActive = true; triedSet = [idx]; clearRetryTimers(); setIframe(idx); loadTimer = setTimeout(function () { onLineFail(idx, '线路加载超时'); }, LOAD_TIMEOUT); } function onLineFail(idx, reason) { if (!retryActive) return; var next = nextUntried(idx); if (next === -1) { stopRetry(); tip('已尝试全部线路,均失败(' + reason + ')。可手动切换线路或关闭“自动换线”。'); return; } triedSet.push(next); tip(reason + ',自动切换至:' + lines[next].name); setIframe(next); loadTimer = setTimeout(function () { onLineFail(next, '线路加载超时'); }, LOAD_TIMEOUT); // watchdog 在 onload 后启动 } // 解析接口页面加载完成:清掉加载超时计时,并启动“超时未播放”看门狗 mIframe.onload = function () { if (loadTimer) { clearTimeout(loadTimer); loadTimer = null; } if (retryActive) { watchTimer = setTimeout(function () { onLineFail(curIdx, '超时未播放'); }, WATCHDOG); } }; /* ---------- 复制:含集数的解析地址 / 原视频地址 ---------- */ function copyParse() { var link = buildLink(curIdx); if (!link) return; var d = detectVideoUrl(); var text = (d.info ? ('【' + d.info + '】 ') : '') + link; tip(doCopy(text) ? ('已复制解析地址:' + (d.info || link)) : ('复制失败,请手动复制:' + link)); } function copyRaw() { var d = detectVideoUrl(); if (!d.url) { tip('请先填入视频地址'); return; } var text = (d.info ? ('【' + d.info + '】 ') : '') + d.url; tip(doCopy(text) ? ('已复制原地址:' + (d.info || d.url)) : ('复制失败,请手动复制:' + d.url)); } /* ---------- 下载当前集(接 AIX 项目) ---------- */ function downloadCurrent() { var d = detectVideoUrl(); if (!d.url) { tip('请先填入视频地址'); return; } var target; if (aixUrl && aixUrl.indexOf('{url}') > -1) { target = aixUrl.replace('{url}', encodeURIComponent(d.url)); } else { target = d.url; // 留空则打开原集数视频页,交给已安装的 AIX 用户脚本/扩展处理 } window.open(target, '_blank'); tip('已为【' + (d.info || '当前视频') + '】打开下载入口' + (aixUrl ? '' : '(未配置AIX入口,已打开原视频页,请确保已装AIX)')); } /* ---------- 播放(弹窗) ---------- */ function play() { if (!buildLink(curIdx)) return; mask.style.display = 'block'; modalOpen = true; if (autoSwitch) startRetryFrom(curIdx); else { stopRetry(); setIframe(curIdx); } } /* ---------- 新窗口 ---------- */ function openNew() { var link = buildLink(curIdx); if (!link) return; window.open(link, '_blank'); } /* ---------- 事件绑定 ---------- */ btn.addEventListener('click', function () { panelOpen = !panelOpen; panel.style.display = panelOpen ? 'block' : 'none'; if (panelOpen) refreshUrl(); }); panel.querySelector('.hd .x').addEventListener('click', function () { panel.style.display = 'none'; panelOpen = false; }); panel.querySelector('#ai-line').addEventListener('change', function (e) { stopRetry(); setIframe(parseInt(e.target.value, 10)); }); panel.querySelector('#ai-play').addEventListener('click', play); panel.querySelector('#ai-new').addEventListener('click', openNew); panel.querySelector('#ai-copy').addEventListener('click', copyParse); panel.querySelector('#ai-copyraw').addEventListener('click', copyRaw); panel.querySelector('#ai-enc').addEventListener('change', function (e) { encodeUrl = e.target.checked; GM_setValue('ai_encode', encodeUrl); if (lines[curIdx]) { lines[curIdx].encode = encodeUrl; saveLines(lines); } }); panel.querySelector('#ai-auto').addEventListener('change', function (e) { autoSwitch = e.target.checked; GM_setValue('ai_autoswitch', autoSwitch); if (!autoSwitch) stopRetry(); }); panel.querySelector('#ai-mgr').addEventListener('click', function () { var box = panel.querySelector('#ai-mgr-box'); box.style.display = (box.style.display === 'block') ? 'none' : 'block'; }); panel.querySelector('#ai-add').addEventListener('click', function () { var n = panel.querySelector('#ai-new-name').value.trim(); var u = panel.querySelector('#ai-new-url').value.trim(); if (!n || !u) { panel.querySelector('#ai-mgr-tip').textContent = '名称和地址都要填'; return; } lines.push({ name: n, url: u, encode: encodeUrl }); saveLines(lines); renderLines(); panel.querySelector('#ai-new-name').value = ''; panel.querySelector('#ai-new-url').value = ''; panel.querySelector('#ai-mgr-tip').textContent = '已添加:' + n; }); panel.querySelector('#ai-del').addEventListener('click', function () { var all = panel.querySelector('#ai-all'); var i = parseInt(all.value, 10); if (isNaN(i)) return; if (lines.length <= 1) { panel.querySelector('#ai-mgr-tip').textContent = '至少保留一条线路'; return; } var removed = lines.splice(i, 1)[0]; if (curIdx >= lines.length) curIdx = lines.length - 1; GM_setValue('ai_line_idx', curIdx); saveLines(lines); renderLines(); panel.querySelector('#ai-mgr-tip').textContent = '已删除:' + removed.name; }); panel.querySelector('#ai-aix-save').addEventListener('click', function () { aixUrl = panel.querySelector('#ai-aix').value.trim(); GM_setValue('ai_aix_url', aixUrl); panel.querySelector('#ai-mgr-tip').textContent = aixUrl ? '已保存 AIX 入口' : '已清空 AIX 入口(将打开原视频页)'; }); /* ---------- 弹窗内事件 ---------- */ mask.querySelector('#ai-m-line').addEventListener('change', function (e) { stopRetry(); setIframe(parseInt(e.target.value, 10)); }); mask.querySelector('#ai-m-retry').addEventListener('click', function () { if (retryActive) { onLineFail(curIdx, '手动换线'); } else { var n = nextUntried(curIdx); if (n === -1) return; startRetryFrom(n); } }); mask.querySelector('#ai-m-dl').addEventListener('click', downloadCurrent); mask.querySelector('#ai-m-new').addEventListener('click', openNew); mask.querySelector('#ai-m-close').addEventListener('click', function () { mask.style.display = 'none'; modalOpen = false; stopRetry(); mIframe.src = 'about:blank'; }); mask.addEventListener('click', function (e) { if (e.target === mask) mask.querySelector('#ai-m-close').click(); }); /* ---------- 快捷键:Ctrl+Shift+J 直接解析当前页 ---------- */ document.addEventListener('keydown', function (e) { if (e.ctrlKey && e.shiftKey && (e.key === 'J' || e.key === 'j')) { e.preventDefault(); refreshUrl(); play(); } }); console.log('[AI视频解析] 已注入(v1.2,含集数识别/自动换线/下载当前集/复制含集数地址)。Ctrl+Shift+J 快捷解析。'); })();