// ==UserScript==
// @name 通用视频搜索
// @namespace http://tampermonkey.net/
// @version 1.5.1
// @description 视频匹配搜索:爱优腾、B站、芒果TV、搜狐、乐视、1905、PPTV、西瓜
// @author tutu辣么可爱
// @include *://*.iqiyi.com/*
// @include *://*.iq.com/*
// @include *://*.youku.com/*
// @include *://*v.qq.com/*
// @include *://*.bilibili.com/*
// @include *://*.acfun.cn/*
// @include *://*.mgtv.com/*
// @include *://*tv.sohu.com/*
// @include *://*.le.com/*
// @include *://*.1905.com/*
// @include *://*.pptv.com/*
// @include *://*.ixigua.com/*
// @license MIT
// ==/UserScript==
(function() {
/*
1.manipulate用于点击/长按事件的设置
2.set用于创建设置页、获取/修改/保存/应用设置数据。data保存设置数据,并通过localstorage的vipParseSettingsData长期保存,保存形式为JSON字符串。backupData保存初始设置数据用于恢复默认。set->createBody->setMenu保存设置页选项数据
3.check用于检查浏览器UA,或通过list检查是否是可生效的网站。list保存脚本可生效的网站ID、名称、域名
4.vip用于创建新播放器,指向解析线路。map保存不同网站不同ua情况下的播放器ID或类名
5.btn用于创建主题按钮。interface保存解析接口,backupInterfa保存初始解析接口数据用于恢复默认
*/
var manipulate = {
data: {
"flag": false,
"wait": false,
"timeStart": 0,
"timeEnd": 0
},
get: function(key) {
if (key === "time") {
return new Date().getTime();
} else {
return this.data[key];
}
},
set: function(key, value) {
this.data[key] = value;
},
start: function(clickEvent, longPressEvent) {
if (!this.get("flag") && !this.get("wait")) {
this.set("flag", true);
this.set("wait", true);
this.set("timeStart", this.get("time"));
setTimeout(function() {
manipulate.end(clickEvent, longPressEvent);
manipulate.set("wait", false);
}, 310);
}
},
end: function(clickEvent, longPressEvent) {
if (this.get("flag")) {
this.set("flag", false);
this.set("timeEnd", this.get("time"));
var timeSpan = this.get("timeEnd") - this.get("timeStart");
if (timeSpan < 300) {
clickEvent();
} else {
longPressEvent();
}
}
},
on: function(target, clickEvent, longPressEvent) {
target.addEventListener("mousedown", function() {
manipulate.start(clickEvent, longPressEvent);
});
target.addEventListener("touchstart", function() {
manipulate.start(clickEvent, longPressEvent);
});
target.addEventListener("mouseup", function() {
manipulate.end(clickEvent, longPressEvent);
});
target.addEventListener("touchend", function() {
manipulate.end(clickEvent, longPressEvent);
});
}
};
var set = {
data: {
"box-top": "100px",
"box-right": "2px",
"main-height": "30px",
"main-width": "50px",
"main-border-radius": "20px",
"menu-height": "310px",
"menu-width": "120px",
"menu-border-radius": "20px",
"item-font-size": "18px",
"item-color": "white",
"background": "rgb(217, 6, 9)",
"user-interface": []
},
backupData: {},
init: function() {
this.backupData = this.data;
var localData = JSON.parse(localStorage.getItem("vipParseSettingsData"));
if (localData) {
var newData = {
...this.data,
...localData
};
this.data = newData;
}
btn.backup();
btn.init();
this.store();
},
get: function(key) {
return this.data[key];
},
edit: function(key, value) {
if (key.search("user-interface") !== -1) {
key = parseInt(key.replace(/[^0-9]/ig, ""));
this.data["user-interface"][key] = value;
}
this.data[key] = value;
},
store: function() {
localStorage.setItem("vipParseSettingsData", JSON.stringify(this.data));
},
save: function() {
var setPage = document.getElementById("vipParseBtnSetting");
var inputBox = setPage.getElementsByTagName("input");
for (let i = 0; i < inputBox.length; i++) {
this.edit(inputBox[i].name, inputBox[i].value);
}
btn.init();
},
apply: function() {
var flag = false;
if (document.getElementById("vipParseBtnMenu").style.display !== "none") {
flag = true;
}
document.getElementById("vipParseBtnBox").remove();
btn.create();
if (flag) {
btn.clickMain();
}
document.getElementById("vipParseBtnSetting").style.background = this.get("background");
},
revert: function() {
var setPage = document.getElementById("vipParseBtnSetting-StyleSet");
if (setPage.style.display === "none") {
setPage = document.getElementById("vipParseBtnSetting-ParseSet");
}
var inputBox = setPage.getElementsByTagName("input");
var interfaceBackup = btn.get("backup");
for (let i in inputBox) {
let key = inputBox[i].name;
if (key.search("user-interface") !== -1) {
key = parseInt(key.replace(/[^0-9]/ig, ""));
inputBox[i].value = interfaceBackup[key];
} else {
inputBox[i].value = this.backupData[key];
}
}
},
switch: function() {
var setTitle = document.getElementById("vipParseBtnSetting-head").children[0];
var styleSet = document.getElementById("vipParseBtnSetting-StyleSet");
var parseSet = document.getElementById("vipParseBtnSetting-ParseSet");
if (styleSet.style.display === "none") {
styleSet.style.display = "";
parseSet.style.display = "none";
setTitle.innerText = "脚本样式设置";
} else {
styleSet.style.display = "none";
parseSet.style.display = "";
setTitle.innerText = "脚本解析设置";
}
},
create: function() {
var setting = document.createElement("div");
var wid = 400;
var hei = 260;
var screenW = document.documentElement.clientWidth;
var screenH = document.documentElement.clientHeight;
if ((wid + 10) > screenW) {
wid = screenW - 10;
}
var settingH = (screenH - hei) / 2;
var settingW = (screenW - wid) / 2;
setting.style =
"display:none;width:" + wid + "px;height:" + hei +
"px;overflow:hidden;position:fixed;top:" + settingH + "px;right:" + settingW +
"px;border-radius:15px;padding:20px;background:" + this.get("background") +
";color:white;font-size:12px;overflow-y:auto;z-index: 99999;";
setting.id = "vipParseBtnSetting";
setting.appendChild(this.createHead());
setting.appendChild(this.createBody());
setting.appendChild(this.createFoot());
document.body.insertBefore(setting, document.body.firstChild);
},
createHead: function() {
var head = document.createElement("div");
var title = document.createElement("span");
var subtitle = document.createElement("span");
head.id = "vipParseBtnSetting-head";
head.style = "width:100%;height:30px;text-align:center;margin-bottom:20px;";
title.style = "font-size:20px;";
title.innerText = "脚本样式设置";
subtitle.style = "font-size:12px;";
subtitle.innerText = "(仅对" + (check.ua() === "pc" ? "桌面端" : "移动端") + check.site("name") + "生效)";
head.appendChild(title);
head.appendChild(subtitle);
return head;
},
createBody: function() {
var body = document.createElement("div");
body.style = "width:115%;height:calc(100% - 80px);overflow: hidden scroll;";
body.id = "vipParseBtnSetting-body";
body.appendChild(this.createStyle());
body.appendChild(this.createParse());
return body;
},
createFoot: function() {
var foot = document.createElement("div");
foot.style = "width:100%;height:30px;position:absolute;bottom:10px;";
foot.id = "vipParseBtnSetting-foot";
foot.appendChild(this.createBtn("revert"));
foot.appendChild(this.createBtn("save"));
foot.appendChild(this.createBtn("close"));
foot.appendChild(this.createBtn("switch"));
return foot;
},
createOpt: function(data, titleWidth, inputWidth) {
var optBox = document.createElement("div");
var titleBox = document.createElement("span");
var textBox = document.createElement("input");
var textBoxMaxWidth = document.documentElement.clientWidth - 20 - titleWidth;
optBox.style = "height:30px;float:left;"
titleBox.innerText = data.name;
titleBox.style = "width:" + titleWidth + "px;float:left;margin-bottom:8px;";
textBox.name = data.key;
textBox.style = "width:" + inputWidth +
"px;max-width:" + textBoxMaxWidth +
"px;float:left;color:black;margin-bottom:8px;margin-right:10px;";
if (data.value) {
textBox.value = data.value;
} else {
textBox.value = set.get(data.key);
}
optBox.appendChild(titleBox);
optBox.appendChild(textBox);
return optBox;
},
createStyle: function() {
var page = document.createElement("div");
page.style = "width:100%;height:100%;";
page.id = "vipParseBtnSetting-StyleSet";
var setMenu = [{
"name": "按钮距离顶部",
"key": "box-top"
}, {
"name": "按钮距离右侧",
"key": "box-right"
}, {
"name": "按钮高度",
"key": "main-height"
}, {
"name": "按钮宽度",
"key": "main-width"
}, {
"name": "按钮圆角",
"key": "main-border-radius"
}, {
"name": "菜单圆角",
"key": "menu-border-radius"
}, {
"name": "菜单高度",
"key": "menu-height"
}, {
"name": "菜单宽度",
"key": "menu-width"
}, {
"name": "菜单字体大小",
"key": "item-font-size"
}, {
"name": "菜单字体颜色",
"key": "item-color"
}, {
"name": "主题背景色调",
"key": "background"
}];
for (let i in setMenu) {
page.appendChild(this.createOpt(setMenu[i], 90, 90));
}
return page;
},
createParse: function() {
var page = document.createElement("div");
page.style = "display:none;width:100%;height:100%;";
page.id = "vipParseBtnSetting-ParseSet";
for (let i = 0; i < btn.get("length"); i++) {
var setdata = {
"name": "播放线路" + ((i + 1) < 10 ? "0" : "") + (i + 1),
"key": "user-interface-" + i,
"value": btn.get(i)
};
page.appendChild(this.createOpt(setdata, 90, 180));
}
return page;
},
createBtn: function(name) {
var btnBox = document.createElement("span");
var btnObj = document.createElement("div");
var text, func, id;
btnObj.style =
"margin-right:12px;padding:0 10px;cursor:pointer;border:white thin solid;border-radius:10px;float:left";
switch (name) {
case "revert":
text = "重置";
id = "vipParseBtnSetting-" + name + "Btn";
func = function() {
set.revert()
}
break;
case "save":
text = "保存并应用";
id = "vipParseBtnSetting-" + name + "Btn";
func = function() {
if (confirm("是否确认保存并应用新设置?")) {
set.save();
set.store();
set.apply();
}
}
break;
case "close":
text = "关闭设置";
id = "vipParseBtnSetting-" + name + "Btn";
func = function() {
var setting = document.getElementById("vipParseBtnSetting");
setting.style.display = "none";
}
break;
case "switch":
text = "切换设置项";
id = "vipParseBtnSetting-" + name + "Btn";
func = function() {
set.switch();
}
break;
default:
break;
}
btnObj.innerText = text;
btnObj.id = id;
btnObj.onclick = func;
btnBox.appendChild(btnObj);
return btnBox;
}
};
var check = {
list: {
0: {
"id": "iqiyi",
"name": "爱奇艺",
"host": "iqiyi.com|iq.com"
},
1: {
"id": "youku",
"name": "优酷",
"host": "youku.com"
},
2: {
"id": "tencentvideo",
"name": "腾讯视频",
"host": "v.qq.com"
},
3: {
"id": "bilibili",
"name": "B站",
"host": "bilibili.com"
},
4: {
"id": "acfun",
"name": "A站",
"host": "acfun.cn"
},
5: {
"id": "mgtv",
"name": "芒果TV",
"host": "mgtv.com"
},
6: {
"id": "sohu",
"name": "搜狐视频",
"host": "tv.sohu.com"
},
7: {
"id": "le",
"name": "乐视视频",
"host": "le.com"
},
8: {
"id": "1905",
"name": "1905电影网",
"host": "1905.com"
},
9: {
"id": "pptv",
"name": "PP视频",
"host": "pptv.com"
},
10: {
"id": "xigua",
"name": "西瓜视频",
"host": "ixigua.com"
}
},
ua: function() {
var uaStr = "pc";
if (/Android|webOS|HarmonyOS|iPhone|iPod|BlackBerry|mobile/i.test(navigator.userAgent)) {
uaStr = "mobile";
}
return uaStr;
},
site: function(type) {
var site = "unknow";
var host = location.hostname;
for (let i in this.list) {
if (host.match(new RegExp(this.list[i].host))) {
site = this.list[i][type];
}
}
return site;
},
url: function(urlStr) {
var res = false;
urlStr = urlStr.replace(/\s+/g, "");
if (/^((http|https):\/\/)?(([A-Za-z0-9]+-[A-Za-z0-9]+|[A-Za-z0-9]+)\.)+([A-Za-z]+)[/\?\:]?.*$/i
.test(urlStr)) {
res = urlStr;
}
return res;
}
}
var vip = {
map: {
"iqiyi": {
"pc": "flashbox",
"mobile": "m-box"
},
"youku": {
"pc": "ykPlayer",
"mobile": "h5-detail-player"
},
"tencentvideo": {
"pc": "mod_player",
"mobile": "mod_player"
},
"bilibili": {
"pc": "bilibili-player-video-wrap|player-limit-mask",
"mobile": "bilibiliPlayer|player-wrapper"
},
"acfun": {
"pc": "ACPlayer",
"mobile": "#ACPlayer"
},
"mgtv": {
"pc": "mgtv-player-wrap",
"mobile": "video-area"
},
"sohu": {
"pc": "x-player",
"mobile": "player-view"
},
"le": {
"pc": "fla_box",
"mobile": "playB"
},
"1905": {
"pc": "player",
"mobile": "player"
},
"pptv": {
"pc": "pplive-player",
"mobile": "pp-details-video"
},
"xigua": {
"pc": "teleplayPage__playerSection__left",
"mobile": "xigua-detailvideo-video-inner"
}
},
get: function(site, ua) {
var res = false;
if (site && ua) {
var key = this.map[site][ua];
if (key) {
key = key.split("|");
for (let i = 0; i < key.length; i++) {
res = this.search(key[i]);
if (res) {
break;
}
}
}
}
return res;
},
search: function(key) {
var player = document.getElementById(key);
if (player) {
return player;
}
player = document.getElementsByClassName(key)[0];
if (player) {
return player;
}
player = false;
return player;
},
on: function() {
var site = check.site("id");
if (site !== "unknow") {
set.init();
set.create();
btn.create();
}
}
}
var btn = {
interface: ["https://z1.m1907.cn/?eps=0&jx=", "https://vip.parwix.com:4433/player/?url=",
"https://vip.bljiex.com/?v=", "https://lecurl.cn/?url=", "https://jx.m3u8.tv/jiexi/?url=",
"https://api.leduotv.com/wp-api/ifr.php?isDp=1&vid=", "https://okjx.cc/?url=",
"https://m2090.com/?url=", "http://51wujin.net/?url=", "https://vip.2ktvb.com/player/?url=",
"https://660e.com/?url=", "https://api.sigujx.com/?url=", "https://jiexi.janan.net/jiexi/?url=",
"https://jx.618g.com/?url=", "https://jx.ergan.top/?url=", "https://api.147g.cc/m3u8.php?url=",
"http://17kyun.com/api.php?url=", "", "", ""
],
backupInterface: [],
get: function(key) {
var res;
if (/^\d+$/.test(key)) {
res = this.interface[key];
} else if (key === "length") {
res = this.interface.length;
} else if (key === "backup") {
res = this.backupInterface;
} else {
res = this.interface;
}
return res;
},
edit: function(key, value) {
if (/^\d+$/.test(key)) {
this.interface[key] = value;
}
},
backup: function() {
for (let i in this.interface) {
this.backupInterface[i] = this.interface[i];
}
},
init: function() {
var interfaceData = set.get("user-interface");
for (let i in interfaceData) {
if (this.get(i) === interfaceData[i]) {
delete interfaceData[i];
} else if (interfaceData[i]) {
this.edit(i, interfaceData[i]);
}
}
set.edit("user-interface", interfaceData);
},
create: function() {
var box = document.createElement("div");
box.style = "cursor: pointer; position: fixed; top: " + set.get("box-top") + ";right: " + set
.get("box-right") + ";z-index: 99999;";
box.id = "vipParseBtnBox";
var main = this.createMain();
var menu = this.createMenu();
box.appendChild(main);
box.appendChild(menu);
document.body.insertBefore(box, document.body.firstChild);
},
createMain: function() {
var main = document.createElement("div");
var pH = set.get("main-height");
pH = (pH.slice(0, pH.search("px")) - 30) / 2;
var pW = set.get("main-width");
pW = (pW.slice(0, pW.search("px")) - 50) / 2;
main.style =
"height:" + set.get("main-height") + ";width:" + set.get("main-width") + ";background:" +
set.get("background") + ";border-radius:" + set.get("main-border-radius") +
";box-sizing:border-box;padding:" + pH + "px " + pW + "px;";
main.id = "vipParseBtnMain";
main.innerHTML =
"<svg height='30' width='50'><polygon points='20,6 35,15 20,24' style='fill:white;'/></svg>";
manipulate.on(main, btn.clickMain, btn.longPressMain);
return main;
},
createMenu: function() {
var menu = document.createElement("div");
var posTop = set.get("main-height");
posTop = posTop.slice(0, posTop.search("px"));
posTop = parseFloat(posTop) + 5;
menu.style =
"display:none;width:" + set.get("menu-width") + ";height:" + set.get("menu-height") +
";overflow:hidden;position:absolute;top:" + posTop + "px;right:0px;border-radius:" + set
.get(
"menu-border-radius") + ";transition: all 0.2s";
menu.id = "vipParseBtnMenu";
var innerMenu = document.createElement("div");
innerMenu.style = "width:115%;height:100%;overflow-y:scroll;overflow-x:hidden;";
for (let i = 0; i < this.get("length"); i++) {
innerMenu.appendChild(this.createItem(i, this.get(i)));
}
menu.appendChild(innerMenu);
return menu;
},
createItem: function(i, url) {
var item = document.createElement("span");
item.style =
"color:" + set.get("item-color") + ";font-size:" + set.get("item-font-size") +
";display:block;padding:10px 6px 6px 10px;width:calc(100% + 30px);background:" + set.get(
"background") + ";border-bottom:white solid;"
item.setAttribute("url", url);
item.innerText = "播放线路 " + ((i + 1) < 10 ? "0" : "") + (i + 1);
item.onclick = function() {
url = check.url(url);
if (url) {
btn.clickItem(url);
console.log("当前解析接口:" + url);
} else {
var msg = "当前解析接口为空,或接口URL错误";
console.log(msg);
alert(msg);
}
}
item.onmouseover = function() {
this.style.background = set.get("item-color");
this.style.color = set.get("background");
}
item.onmouseleave = function() {
this.style.background = set.get("background");
this.style.color = set.get("item-color");
}
return item;
},
clickMain: function() {
var menu = document.getElementById("vipParseBtnMenu");
if (menu.style.display !== "none") {
menu.style.display = "none";
} else {
menu.style.display = "block";
}
},
longPressMain: function() {
var setting = document.getElementById("vipParseBtnSetting");
if (setting.style.display !== "none") {
setting.style.display = "none";
} else {
setting.style.display = "block";
}
},
clickItem: function(url) {
var newPlayer = document.createElement("iframe");
newPlayer.frameBorder = "no";
newPlayer.width = "100%";
newPlayer.height = "100%";
newPlayer.allowFullscreen = "true";
newPlayer.allowTransparency = "true";
newPlayer.scrolling = "no";
newPlayer.id = "newPlayerParseIframe";
newPlayer.src = url + location.href;
var player = vip.get(check.site("id"), check.ua());
if (player) {
var originHeight = player.clientHeight;
player.innerHTML = "";
player.style.height = originHeight + "px";
player.appendChild(newPlayer);
}
}
}
vip.on();
})();