// ==UserScript==
// @name 🎬【VIP追剧神器】【free】支持多平台
// @namespace http://tampermonkey.net/
// @version 2.0.0
// @description ▶在线VIP视频解析工具 |free| 支持多平台<在不看VIP电影时关闭脚本>【爱奇艺】【腾讯视频】【优酷土豆】【芒果TV】【乐视视频】【哔哩哔哩】【搜狐视频】等常见视频平台。提供多种解析接口,支持内嵌播放和弹窗播放模式,可自动解析VIP视频。制作不易,熬穿了不知道多少个夜晚,您的赞赏会是刺破黑暗苍穹的亮照照亮我前行的路❗❗❗有问题可加微信咨询:Why15236444193[学长也还有学业在身,如果加微信未能及时回复,请多多包涵哈!
// @author 伏黑甚而
// @match *://*/*
// @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-start
// @icon data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgdmlld0JveD0iMCAwIDMyIDMyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTE2IDMuNWMtNi45IDAtMTIuNSA1LjYtMTIuNSAxMi41UzkuMSAyOC41IDE2IDI4LjUgMjguNSAyMi45IDI4LjUgMTYgMjIuOSAzLjUgMTYgMy41eiIgZmlsbD0iI2ZmNjliNCIvPjxwYXRoIGQ9Ik0xNiA2LjVjLTUuMiAwLTkuNSA0LjMtOS41IDkuNXM0LjMgOS41IDkuNSA5LjUgOS41LTQuMyA5LjUtOS41LTQuMy05LjUtOS41LTkuNXptMCAxNmMtMy42IDAtNi41LTIuOS02LjUtNi41czIuOS02LjUgNi41LTYuNSA2LjUgMi45IDYuNSA2LjUtMi45IDYuNS02LjUgNi41eiIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0xMiAxNWgydjJoLTJ6bTQtMmgzdjJoLTN6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTE0IDIyaC0ydjJoMnoiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNMTggMjJoLTJ2MmgyeiIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0xNSAyN2gydjJoLTJ6IiBmaWxsPSIjZmZmIi8+PC9zdmc+
// ==/UserScript==
(function() {
'use strict';
// 解析接口配置 - 去重整合后的完整列表
const parseApis = [
// 类型1: 内嵌播放 + 弹窗无选集
{"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": "纯净1", "type": "1,2,3", "url": "https://im1907.top/?jx="},
{"name": "B站1", "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": "思古3", "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": "M3U8TV", "type": "1,3", "url": "https://jx.m3u8.tv/jiexi/?url="},
{"name": "playm3u8", "type": "1,3", "url": "https://www.playm3u8.cn/jiexi.php?url="},
{"name": "综合", "type": "1,3", "url": "https://jx.jsonplayer.com/player/?url="},
// 类型2: 弹窗播放带选集(仅保留正确的接口)
{"name": "im1907", "type": "2", "url": "https://im1907.top/?jx="},
{"name": "云析(带选集)", "type": "2", "url": "https://jx.yparse.com/index.php?url="},
];
// 去重处理 - 确保URL唯一的接口
const uniqueApis = [];
const seenUrls = new Set();
parseApis.forEach(api => {
if (!seenUrls.has(api.url)) {
seenUrls.add(api.url);
uniqueApis.push(api);
}
});
// 获取用户自定义接口
const customApis = GM_getValue("custom_parse_apis", []);
// 合并内置接口和自定义接口
const allApis = [...uniqueApis, ...customApis];
const CONFIG = {
vipBoxId: 'vip_jx_box_' + Math.ceil(Math.random() * 100000000),
autoPlayerKey: "auto_player_key_" + window.location.host,
autoPlayerVal: "auto_player_value_" + window.location.host,
flag: "flag_vip",
// 添加当前选中的类型存储键
currentTypeKey: "current_type_key_" + window.location.host
};
// 添加样式
GM_addStyle(`
#${CONFIG.vipBoxId} {
cursor: pointer;
position: fixed;
top: 120px;
left: -24px; /* 修改为-24px */
z-index: 9999999;
text-align: left;
transition: left 0.3s ease; /* 添加平滑过渡效果 */
}
#${CONFIG.vipBoxId}.visible {
left: 0px; /* 鼠标悬停时完全显示 */
}
#${CONFIG.vipBoxId} .img_box {
width: 32px;
height: 32px;
line-height: 32px;
text-align: center;
background-color: lightgreen; /* 修改为浅绿色背景 */
margin: 10px 0px;
color: white;
font-size: 16px;
font-weight: bold;
border-radius: 5px;
}
#${CONFIG.vipBoxId} .vip_list {
display: none;
position: absolute;
border-radius: 5px;
left: 32px;
top: 0;
text-align: center;
background-color: #3f4149;
border: 1px solid white;
padding: 10px 0px;
width: 380px;
max-height: 400px;
overflow-y: auto;
opacity: 0;
transform: translateX(-10px);
transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
}
#${CONFIG.vipBoxId} .vip_list.visible {
display: block;
opacity: 1;
transform: translateX(0);
}
#${CONFIG.vipBoxId} .vip_list ul {
padding-left: 10px;
}
#${CONFIG.vipBoxId} .vip_list li {
border-radius: 2px;
font-size: 12px;
color: #DCDCDC;
text-align: center;
width: calc(25% - 14px); /* 每行显示4个 */
line-height: 21px;
float: left;
border: 1px solid gray;
padding: 0 4px;
margin: 4px 2px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
opacity: 0;
transform: translateY(10px);
}
#${CONFIG.vipBoxId} .vip_list.visible li {
opacity: 1;
transform: translateY(0);
transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1) 0.1s;
}
/* 弹窗带选集接口每行显示2个 */
#${CONFIG.vipBoxId} .complex-api-list li {
width: calc(50% - 14px);
}
#${CONFIG.vipBoxId} .vip_list li:hover {
color: #1c84c6;
border: 1px solid #1c84c6;
}
#${CONFIG.vipBoxId} .vip_list::-webkit-scrollbar {
width: 5px;
height: 1px;
}
#${CONFIG.vipBoxId} .vip_list::-webkit-scrollbar-thumb {
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
background: #A8A8A8;
}
#${CONFIG.vipBoxId} .vip_list::-webkit-scrollbar-track {
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
background: #F1F1F1;
}
#${CONFIG.vipBoxId} li.selected {
color: #1c84c6;
border: 1px solid #1c84c6;
}
#${CONFIG.vipBoxId} #vip_auto {
background-color: #ff69b4; /* 粉色背景 */
}
#${CONFIG.vipBoxId} #add_api_btn {
background-color: #36383f;
color: #ccc;
border: 1px solid #5a5a5a;
font-size: 12px;
width: auto;
padding: 6px 12px;
margin-top: 5px;
border-radius: 3px;
}
#${CONFIG.vipBoxId} #add_api_btn:hover {
background-color: #42444a;
}
/* 新增样式:用于区分接口名称和播放模式 */
.mode-toggle {
color: #1c84c6;
cursor: pointer;
margin-left: 2px;
}
.section-title {
color: #1c84c6;
font-weight: bold;
font-size: 14px;
padding: 5px 0px;
clear: both;
opacity: 0;
transform: translateY(10px);
}
#${CONFIG.vipBoxId} .vip_list.visible .section-title {
opacity: 1;
transform: translateY(0);
transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1) 0.05s;
}
/* 赞赏码相关样式 */
#${CONFIG.vipBoxId} #donate_section {
clear: both;
margin-top: 10px;
padding: 10px;
text-align: center;
border-top: 1px solid #555;
opacity: 0;
transform: translateY(10px);
}
#${CONFIG.vipBoxId} .vip_list.visible #donate_section {
opacity: 1;
transform: translateY(0);
transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1) 0.15s;
}
#${CONFIG.vipBoxId} #donate_section .donate-title {
color: #f8ac59;
font-size: 12px;
margin-bottom: 5px;
}
#${CONFIG.vipBoxId} #qr-code-img {
max-width: 100px;
max-height: 100px;
margin-top: 5px;
border: 1px solid #ddd;
background: white;
}
/* 选项卡样式 */
#${CONFIG.vipBoxId} .tab-header {
display: flex;
background-color: #3f4149;
}
#${CONFIG.vipBoxId} .tab-button {
flex: 1;
padding: 5px 0;
border: none;
cursor: pointer;
outline: none;
font-size: 12px;
background: none;
color: #ccc;
}
#${CONFIG.vipBoxId} .tab-button.active {
color: #1c84c6;
font-weight: bold;
}
#${CONFIG.vipBoxId} .tab-divider {
width: 1px;
background-color: #5a5a5a;
margin: 5px 0;
}
#${CONFIG.vipBoxId} .tab-content {
display: none;
}
#${CONFIG.vipBoxId} .tab-content.active {
display: block;
}
#${CONFIG.vipBoxId} .add-api-form {
padding: 10px;
background-color: #3f4149;
border-radius: 4px;
margin: 10px;
display: none;
}
#${CONFIG.vipBoxId} .add-api-form input,
#${CONFIG.vipBoxId} .add-api-form select {
width: 100%;
padding: 6px;
margin: 5px 0;
border-radius: 3px;
border: 1px solid #5a5a5a;
background-color: #2c2e34;
color: #ccc;
}
#${CONFIG.vipBoxId} .add-api-form button {
padding: 6px 12px;
margin: 5px 2px;
border: none;
border-radius: 3px;
cursor: pointer;
background-color: #1c84c6;
color: white;
}
#${CONFIG.vipBoxId} .add-api-form .cancel-btn {
background-color: #72747a;
}
#${CONFIG.vipBoxId} #add_api_btn {
background-color: #36383f;
color: #ccc;
border: 1px solid #5a5a5a;
font-size: 12px;
width: auto;
padding: 6px 12px;
margin-top: 5px;
border-radius: 3px;
}
#${CONFIG.vipBoxId} #add_api_btn:hover {
background-color: #42444a;
}
`);
// 查找目标元素的工具函数
function findTargetElement(targetContainer) {
const body = window.document;
let tabContainer;
let tryTime = 0;
const maxTryTime = 120;
let startTimestamp;
return new Promise((resolve, reject) => {
function tryFindElement(timestamp) {
if (!startTimestamp) {
startTimestamp = timestamp;
}
const elapsedTime = timestamp - startTimestamp;
if (elapsedTime >= 500) {
//console.log("查找元素:" + targetContainer + ",第" + tryTime + "次");
tabContainer = body.querySelector(targetContainer);
if (tabContainer) {
resolve(tabContainer);
} else if (++tryTime === maxTryTime) {
reject();
} else {
startTimestamp = timestamp;
}
}
if (!tabContainer && tryTime < maxTryTime) {
requestAnimationFrame(tryFindElement);
}
}
requestAnimationFrame(tryFindElement);
});
}
// 创建VIP解析按钮
function createVipButton() {
// 检查是否已经创建过
if (document.getElementById(CONFIG.vipBoxId)) return;
// 获取用户上次选择的类型,默认为"1"(内嵌播放)
let currentType = GM_getValue(CONFIG.currentTypeKey, "1");
// 分离接口到两个区域
let simpleApisHtml = "
[内嵌播放+弹窗无选集]
";
let complexApisHtml = "[弹窗带选集]
";
allApis.forEach((item, index) => {
const types = item.type.split(',');
const name = item.name;
// 处理简单播放模式(内嵌和弹窗无选集)
if (types.includes("1") || types.includes("3")) {
// 只有同时支持1和3或者只支持其中一种的接口才属于此类
if ((types.includes("1") || types.includes("3")) && !types.includes("2")) {
if (types.includes("1") && types.includes("3")) {
// 同时支持内嵌和弹窗无选集
simpleApisHtml += `- ${name} | 内嵌
`;
} else if (types.includes("1")) {
// 仅支持内嵌
simpleApisHtml += `- ${name} | 内嵌
`;
} else if (types.includes("3")) {
// 仅支持弹窗无选集
simpleApisHtml += `- ${name} | 弹窗
`;
}
}
// 特殊处理同时支持三种类型的接口,将其分别归类
if (types.includes("1") && types.includes("2") && types.includes("3")) {
// 在简单播放模式中只显示内嵌和弹窗无选集部分
simpleApisHtml += `- ${name} | 内嵌
`;
}
}
// 处理复杂播放模式(弹窗带选集)
if (types.includes("2")) {
// 专门处理弹窗带选集的接口,不支持模式切换
complexApisHtml += `- ${name}
`;
}
});
simpleApisHtml += "
";
complexApisHtml += "
";
// 添加自定义接口和赞赏功能分支
let customAndDonateHtml = `
`;
let autoPlay = !!GM_getValue(CONFIG.autoPlayerKey, null) ? "开" : "关";
const vipBox = document.createElement('div');
vipBox.id = CONFIG.vipBoxId;
vipBox.innerHTML = `
VIP
${simpleApisHtml}
${complexApisHtml}
自动解析功能说明:
1、自动解析功能默认关闭(自动解析只支持内嵌播放源)
2、开启自动解析,网页打开后脚本将根据当前选中的解析源自动解析视频。如解析失败,请手动选择不同的解析源尝试
3、没有选中解析源将随机选取一个
4、如某些网站有会员可以关闭自动解析功能
5、点击接口名称后的模式标签可以切换播放模式
${customAndDonateHtml}
${autoPlay}
`;
// 使用与第一个脚本相同的查找机制来确定按钮插入位置
findTargetElement('body')
.then((container) => {
container.appendChild(vipBox);
// 绑定事件
bindEvents();
// 自动播放功能
if (!!GM_getValue(CONFIG.autoPlayerKey, null)) {
setTimeout(() => {
autoPlayVideo();
}, 2500);
}
})
.catch(() => {
// 如果找不到body,则直接添加到document
document.body.appendChild(vipBox);
bindEvents();
if (!!GM_getValue(CONFIG.autoPlayerKey, null)) {
setTimeout(() => {
autoPlayVideo();
}, 2500);
}
});
}
// 切换播放模式
function togglePlayMode(element) {
const listItem = element.closest('.api-item');
const modes = listItem.dataset.modes.split(',');
const currentMode = listItem.dataset.currentMode;
// 找到下一个模式
let nextModeIndex = modes.indexOf(currentMode) + 1;
if (nextModeIndex >= modes.length) nextModeIndex = 0;
const nextMode = modes[nextModeIndex];
// 更新显示文本
let modeText = "";
switch(nextMode) {
case "1": modeText = "内嵌"; break;
case "3": modeText = "弹窗"; break;
default: modeText = "未知";
}
element.textContent = modeText;
// 更新数据属性
listItem.dataset.currentMode = nextMode;
}
// 绑定解析接口面板事件
function bindEvents() {
const vipBox = document.getElementById(CONFIG.vipBoxId);
// 鼠标悬停显示/隐藏
vipBox.querySelector(".vip_icon").addEventListener("mouseover", () => {
vipBox.classList.add("visible");
const vipList = vipBox.querySelector(".vip_list");
vipList.classList.add("visible");
// 延迟显示子元素以创建级联效果
setTimeout(() => {
const items = vipList.querySelectorAll('li, .section-title, #donate_section');
items.forEach((item, index) => {
setTimeout(() => {
item.style.transitionDelay = '0ms';
}, index * 30);
});
}, 50);
});
vipBox.querySelector(".vip_icon").addEventListener("mouseout", () => {
const vipList = vipBox.querySelector(".vip_list");
vipList.classList.remove("visible");
vipBox.classList.remove("visible");
// 重置子元素的过渡延迟
const items = vipList.querySelectorAll('li, .section-title, #donate_section');
items.forEach(item => {
item.style.transitionDelay = '';
});
});
// 选项卡切换功能
const tabButtons = vipBox.querySelectorAll(".tab-button");
tabButtons.forEach(button => {
button.addEventListener("click", function() {
// 移除所有活动状态
tabButtons.forEach(btn => btn.classList.remove("active"));
vipBox.querySelectorAll(".tab-content").forEach(content => content.classList.remove("active"));
// 添加活动状态到当前选项卡
this.classList.add("active");
const tabId = this.getAttribute("data-tab");
vipBox.querySelector(`#${tabId}-tab`).classList.add("active");
});
});
// 添加自定义接口按钮事件绑定
const addApiBtn = vipBox.querySelector("#add_api_btn");
if (addApiBtn) {
addApiBtn.addEventListener("click", function(e) {
e.stopPropagation();
const form = vipBox.querySelector("#add-api-form");
form.style.display = form.style.display === "block" ? "none" : "block";
});
}
// 添加保存接口事件
const saveApiBtn = vipBox.querySelector("#save-api-btn");
if (saveApiBtn) {
saveApiBtn.addEventListener("click", function(e) {
e.stopPropagation();
const nameInput = vipBox.querySelector("#api-name");
const urlInput = vipBox.querySelector("#api-url");
const typeSelect = vipBox.querySelector("#api-type");
const name = nameInput.value.trim();
const url = urlInput.value.trim();
const type = typeSelect.value;
if (!name || !url) {
alert('请填写完整信息');
return;
}
if (!url.includes('?url=') && !url.includes('&url=')) {
alert('接口地址必须包含 "?url=" 或 "&url=" 参数占位符');
return;
}
const newApi = {
name: name,
type: type,
url: url
};
// 保存到自定义接口列表
const customApis = GM_getValue("custom_parse_apis", []);
customApis.push(newApi);
GM_setValue("custom_parse_apis", customApis);
// 清空表单
nameInput.value = '';
urlInput.value = '';
// 隐藏表单
vipBox.querySelector("#add-api-form").style.display = "none";
alert('自定义接口已添加,刷新页面后即可使用');
});
}
// 添加取消按钮事件
const cancelApiBtn = vipBox.querySelector("#cancel-api-btn");
if (cancelApiBtn) {
cancelApiBtn.addEventListener("click", function(e) {
e.stopPropagation();
vipBox.querySelector("#add-api-form").style.display = "none";
});
}
// 解析接口点击事件(统一处理)
vipBox.querySelectorAll(".api-item").forEach(item => {
item.addEventListener("click", (e) => {
// 检查是否点击了模式切换区域
if (e.target.classList.contains('mode-toggle')) {
togglePlayMode(e.target);
return;
}
const index = parseInt(item.getAttribute("data-index"));
const videoObj = allApis[index];
// 获取播放模式
let apiType;
if (item.classList.contains('combined-simple')) {
// 组合接口,使用当前选中的模式
apiType = item.dataset.currentMode;
} else {
// 普通接口
apiType = item.getAttribute("data-mode");
}
// 根据类型执行不同操作
if (apiType === "1") {
// 内嵌播放
GM_setValue(CONFIG.autoPlayerVal, index);
GM_setValue(CONFIG.flag, "true");
playVideo(videoObj, true);
// 更新选中状态
vipBox.querySelectorAll(".api-item").forEach(li => {
li.classList.remove("selected");
});
item.classList.add("selected");
} else {
// 弹窗播放(2和3类型)
const url = videoObj.url + window.location.href;
GM_openInTab(url, {active: true, insert: true, setParent: true});
}
});
});
// 自动播放开关
vipBox.querySelector("#vip_auto").addEventListener("click", function() {
if (!!GM_getValue(CONFIG.autoPlayerKey, null)) {
GM_setValue(CONFIG.autoPlayerKey, null);
this.innerHTML = "关";
this.title = "是否打开自动解析。若自动解析失败,请手动选择其它接口尝试!!";
} else {
GM_setValue(CONFIG.autoPlayerKey, "true");
this.innerHTML = "开";
}
setTimeout(() => {
window.location.reload();
}, 200);
});
// 右键拖拽移动位置
vipBox.addEventListener("mousedown", function(e) {
if (e.which !== 3) return;
e.preventDefault();
vipBox.style.cursor = "move";
const positionDiv = vipBox.getBoundingClientRect();
let distenceX = e.clientX - positionDiv.left;
let distenceY = e.clientY - positionDiv.top;
document.addEventListener("mousemove", moveHandler);
document.addEventListener("mouseup", upHandler);
document.addEventListener("contextmenu", contextMenuHandler);
function moveHandler(e) {
let x = e.clientX - distenceX;
let y = e.clientY - distenceY;
const windowWidth = window.innerWidth;
const windowHeight = window.innerHeight;
if (x < 0) x = 0;
else if (x > windowWidth - vipBox.offsetWidth - 100) {
x = windowWidth - vipBox.offsetWidth - 100;
}
if (y < 0) y = 0;
else if (y > windowHeight - vipBox.offsetHeight) {
y = windowHeight - vipBox.offsetHeight;
}
vipBox.style.left = x + "px";
vipBox.style.top = y + "px";
}
function upHandler() {
document.removeEventListener("mousemove", moveHandler);
document.removeEventListener("mouseup", upHandler);
vipBox.style.cursor = "pointer";
}
function contextMenuHandler(e) {
e.preventDefault();
}
});
}
// 添加自定义解析接口
function addCustomApi() {
Swal.fire({
title: '添加自定义解析接口',
html: `
`,
confirmButtonText: '添加',
focusConfirm: false,
preConfirm: () => {
const name = document.getElementById('api-name').value;
const url = document.getElementById('api-url').value;
const type = document.getElementById('api-type').value;
if (!name || !url) {
Swal.showValidationMessage('请填写完整信息');
return false;
}
if (!url.includes('?url=') && !url.includes('&url=')) {
Swal.showValidationMessage('接口地址必须包含 "?url=" 或 "&url=" 参数占位符');
return false;
}
return { name, url, type };
}
}).then(result => {
if (result.isConfirmed) {
const newApi = {
name: result.value.name,
type: result.value.type, // 根据选择的类型设置
url: result.value.url
};
// 保存到自定义接口列表
const customApis = GM_getValue("custom_parse_apis", []);
customApis.push(newApi);
GM_setValue("custom_parse_apis", customApis);
Swal.fire('添加成功', '自定义接口已添加,刷新页面后即可使用', 'success');
}
});
}
// 播放视频
function playVideo(videoObj, isEmbed) {
if (!isEmbed) return;
// 移除页面上的所有视频元素
const videos = document.getElementsByTagName("video");
for (let video of videos) {
if (video.src) {
video.removeAttribute("src");
video.muted = true;
video.load();
video.pause();
}
}
// 查找合适的容器并替换内容
const containers = [
"#player",
"#mod_player",
"#player-container",
".container-player",
"#mgtv-player-wrap",
"#player_module",
"#bilibiliPlayer",
"#bilibili-player",
"#flashbox",
".m-video-player-wrap",
".intl-video-wrap",
".td-playbox",
"#pptv_playpage_box",
".w-video",
"#flashContent",
"#vodPlayer"
];
let containerFound = false;
for (let selector of containers) {
const container = document.querySelector(selector);
if (container) {
containerFound = true;
// 清空容器
while (container.firstChild) {
container.removeChild(container.firstChild);
}
// 创建iframe播放器
const iframe = document.createElement("iframe");
iframe.src = videoObj.url + window.location.href;
iframe.style.border = "none";
iframe.style.width = "100%";
iframe.style.height = "100%";
iframe.allowFullscreen = true;
// 设置容器样式
container.style.position = "relative";
container.style.width = "100%";
container.style.height = "100%";
container.style.zIndex = "999999";
container.appendChild(iframe);
break;
}
}
if (!containerFound) {
// 如果没找到容器,创建一个新容器
const container = document.createElement("div");
container.id = "vip-video-container";
container.style.position = "fixed";
container.style.top = "0";
container.style.left = "0";
container.style.width = "100%";
container.style.height = "100%";
container.style.zIndex = "9999999";
container.style.backgroundColor = "black";
const iframe = document.createElement("iframe");
iframe.src = videoObj.url + window.location.href;
iframe.style.border = "none";
iframe.style.width = "100%";
iframe.style.height = "100%";
iframe.allowFullscreen = true;
container.appendChild(iframe);
document.body.appendChild(container);
}
}
// 自动播放视频
function autoPlayVideo() {
let index = GM_getValue(CONFIG.autoPlayerVal, 0);
let autoObj = allApis[index];
// 检查是否是内嵌播放类型
if (autoObj.type.includes("1")) {
playVideo(autoObj, true);
const vipBox = document.getElementById(CONFIG.vipBoxId);
if (vipBox) {
const selectedItem = vipBox.querySelector(`.api-item[data-index="${index}"]`);
if (selectedItem) {
selectedItem.classList.add("selected");
}
vipBox.querySelector("#vip_auto").title = `自动解析源:${autoObj.name}`;
}
}
}
// 页面加载完成后创建按钮
// 修改为使用requestAnimationFrame循环检测,确保body元素存在
function waitForBody() {
if (document.body) {
createVipButton();
} else {
requestAnimationFrame(waitForBody);
}
}
// 修改为与第一个脚本一致的初始化方式
const util = {
findTargetEle: (targetEle) => findTargetElement(targetEle)
};
util.findTargetEle('body')
.then(() => {
createVipButton();
})
.catch(() => {
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", waitForBody);
} else {
waitForBody();
}
});
// 菜单注册模块
(function registerMenu() {
GM_registerMenuCommand('🎬 VIP解析窗口', function() {
// 确保按钮可见
const vipBox = document.getElementById(CONFIG.vipBoxId);
if (vipBox) {
vipBox.style.display = "block";
// 展示解析列表
vipBox.querySelector(".vip_list").style.display = "block";
} else {
createVipButton();
}
}, 'v');
GM_registerMenuCommand('📊 脚本状态', function() {
// 直接获取当前脚本版本,不添加回退
const version = GM_info.script.version;
alert('当前版本:' + version + '\\n解析工具已启动,支持多平台VIP视频解析\\n共整合 '+ allApis.length +' 个解析接口\\n新增:多接口选择功能!');
});
GM_registerMenuCommand('➕ 添加自定义接口', function() {
addCustomApi();
});
})();
})();