全网VIP视频自动解析播放器(已适配手机)

无需跳转新网址,打开官网直接看,超清 无广告 随机去水印。支持:腾讯,爱奇艺,优酷,哔哩哔哩,咪咕,乐视,搜狐,芒果,西瓜,PPTV,1905电影网,华数。支持解析失败自动切换推荐解析源。适配各种浏览器,酷睿i5-8300 CPU性能测试消耗仅1%。请关闭浏览器阻止第三方Cookie的功能,否则解析源会解析失败,解析源解析失败作者无力解决。

  1. // ==UserScript==
  2. // @name 全网VIP视频自动解析播放器(已适配手机)
  3. // @namespace https://www.tampermonkey.net/
  4. // @version 1.2
  5. // @homepage https://gf.qytechs.cn/zh-CN/users/840688
  6. // @license AGPL-3.0
  7. // @description 无需跳转新网址,打开官网直接看,超清 无广告 随机去水印。支持:腾讯,爱奇艺,优酷,哔哩哔哩,咪咕,乐视,搜狐,芒果,西瓜,PPTV,1905电影网,华数。支持解析失败自动切换推荐解析源。适配各种浏览器,酷睿i5-8300 CPU性能测试消耗仅1%。请关闭浏览器阻止第三方Cookie的功能,否则解析源会解析失败,解析源解析失败作者无力解决。
  8. // @icon data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgaWQ9IkxheWVyXzEiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUxMiA1MTI7IiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiB4bWw6c3BhY2U9InByZXNlcnZlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLnN0MHtmaWxsOiNFNkU2RTY7fQoJLnN0MXtmaWxsOiM0RDUxNTI7fQoJLnN0MntmaWxsOiM2OUM5Qzk7fQo8L3N0eWxlPjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0yNTUuOCwxOS42Yy0xMzAuMywwLTIzNiwxMDUuNi0yMzYsMjM2czEwNS42LDIzNiwyMzYsMjM2czIzNi0xMDUuNiwyMzYtMjM2UzM4Ni4xLDE5LjYsMjU1LjgsMTkuNnogICBNMTgzLjMsMzc0LjlWMjg2aC0xMHYtNjBoMTB2LTg4LjlsMjA2LDExOC45TDE4My4zLDM3NC45eiIvPjxnPjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0yNTUuOSwzMGMxMTMuNSwwLDIwOS45LDg0LjgsMjI0LjIsMTk3LjNsMTkuOC0yLjVDNDg0LjQsMTAyLjMsMzc5LjUsMTAsMjU1LjksMTAgICBDMTkyLDEwLDEzMS40LDM0LjQsODUuNCw3OC43Yy00NS45LDQ0LjItNzIuNiwxMDMuNS03NS4zLDE2N2wyMCwwLjhDMzUuMSwxMjUuMSwxMzQuMywzMCwyNTUuOSwzMHoiLz48cGF0aCBjbGFzcz0ic3QxIiBkPSJNNTAxLjcsMjQ1LjZsLTIwLDAuOGMwLjEsMy4yLDAuMiw2LjQsMC4yLDkuNnMtMC4xLDYuNC0wLjIsOS42bDIwLDAuOGMwLjEtMy40LDAuMi02LjksMC4yLTEwLjQgICBTNTAxLjgsMjQ5LDUwMS43LDI0NS42eiIvPjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0yNTUuOSw0ODJjLTEyMS42LDAtMjIwLjctOTUuMS0yMjUuOC0yMTYuNGwtMjAsMC44YzIuNiw2My41LDI5LjQsMTIyLjgsNzUuMywxNjYuOSAgIGM0Niw0NC4zLDEwNi42LDY4LjcsMTcwLjUsNjguN2MxMjMuNiwwLDIyOC41LTkyLjMsMjQ0LTIxNC43bC0xOS44LTIuNUM0NjUuOCwzOTcuMiwzNjkuNCw0ODIsMjU1LjksNDgyeiIvPjxwb2x5Z29uIGNsYXNzPSJzdDEiIHBvaW50cz0iMTYzLjMsNDA5LjYgNDI5LjMsMjU2IDE2My4zLDEwMi40IDE2My4zLDIyNiAxODMuMywyMjYgMTgzLjMsMTM3LjEgMzg5LjMsMjU2IDE4My4zLDM3NC45IDE4My4zLDI4NiAgICAxNjMuMywyODYgICIvPjxyZWN0IGNsYXNzPSJzdDEiIGhlaWdodD0iMjAiIHdpZHRoPSIyMCIgeD0iMTYzLjMiIHk9IjI0NiIvPjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0yMDMuMywzNDAuM2wxNDYtODQuM2wtMTQ2LTg0LjNWMzQwLjN6IE0yMjMuMywyMDYuM2w4Niw0OS43bC04Niw0OS43VjIwNi4zeiIvPjwvZz48cG9seWdvbiBjbGFzcz0ic3QyIiBwb2ludHM9IjIyMy4zLDIwNi4zIDIyMy4zLDMwNS43IDMwOS4zLDI1NiAiLz48L3N2Zz4=
  9. // @author Tenfond
  10. // @match https://*/*
  11. // @match http://*/*
  12. // @grant none
  13. // @run-at document-start
  14. // ==/UserScript==
  15.  
  16.  
  17. (function () {
  18. const settings = {IntervalIds: []};
  19. // 匹配URL
  20. if (new RegExp("[?&]\\w{1,5}=https?://(?:\\w+\.)?(?:v\\.qq|iqiyi|youku|bilibili|miguvideo|le|(?:tv|film)\\.sohu|mgtv|ixigua|pptv|1905)\\.com|wasu\\.cn/.+").test(location.search)) {
  21. settings.isParse = true;
  22. } else if (// 如果没匹配到 前面不是 非.或非空且匹配项在末尾$ 时则退出。因为 ios系统不兼容 零宽后向断言,所以这里不使用(?<![^.])
  23. (window !== top || !new RegExp("(?:^|\\.)(?:v\\.qq|iqiyi|youku|bilibili|miguvideo|le|(?:tv|film)\\.sohu|mgtv|ixigua|pptv|1905)\\.com|wasu\\.cn$").test(location.host) || new RegExp("(?:space\\.bilibili)\\.com").test(location.host))
  24. ) {
  25. // 如果不匹配则退出
  26. return;
  27. }
  28. (async function () {
  29. 'use strict';
  30.  
  31. console.log("脚本运行在 " + (window === top ? window.name = Date.now().toString(36) : window.name) + " " + location.href);
  32. if (typeof location["#463907"] === "undefined") {
  33. try {
  34. Object.defineProperty(location, "#463907", {
  35. value: "v",
  36. writable: false,
  37. enumerable: false,
  38. configurable: false
  39. });
  40. } catch (e) {
  41. // 防止脚本重复执行
  42. }
  43. } else {
  44. return;
  45. }
  46.  
  47. (function () {
  48. const appendChild = Node.prototype.appendChild;
  49. Node.prototype.appendChild = function (node) {
  50. if (node.constructor.name === "HTMLIFrameElement") {
  51. const src = node.src;
  52. node.removeAttribute("src");
  53. node.removeAttribute("sandbox");
  54. appendChild.apply(this, arguments);
  55. if (document.contains(node)) {
  56. node.contentWindow.name = window.name;
  57. console.log(src + " = " + node.contentWindow.name);
  58. }
  59. // 空的src会导致网页刷新,所以需要排除
  60. if (Boolean(src)) node.src = src;
  61. } else if (typeof node.getElementsByTagName === "function") {
  62. const src = [], iframes = node.getElementsByTagName("iframe");
  63. for (let i = 0; i < iframes.length; i++) {
  64. src[i] = iframes[i].src;
  65. iframes[i].removeAttribute("src");
  66. iframes[i].removeAttribute("sandbox");
  67. }
  68. appendChild.apply(this, arguments);
  69. if (document.contains(node)) {
  70. for (let i = 0; i < iframes.length; i++) {
  71. iframes[i].contentWindow.name = window.name;
  72. console.log(src[i] + " = " + iframes[i].contentWindow.name);
  73. if (Boolean(src[i])) iframes[i].src = src[i];
  74. }
  75. } else {
  76. for (let i = 0; i < iframes.length; i++) {
  77. if (Boolean(src[i])) iframes[i].src = src[i];
  78. }
  79. }
  80. } else {
  81. appendChild.apply(this, arguments);
  82. }
  83. return node;
  84. };
  85. try {
  86. Object.defineProperty(console, "clear", {
  87. value: function () {
  88. console.error("禁止清除控制台");
  89. },
  90. writable: false,
  91. enumerable: true,
  92. configurable: false
  93. });
  94. } catch (e) {
  95. console.error(e.message);
  96. }
  97. })();
  98.  
  99. // 读取配置后执行
  100. function config() {
  101. // 获取框架循环时间,CPU性能好的可以设置为100,CPU性能不好的可以设置为1000
  102. settings.getElementTimes = 500;
  103. // log输出字体布局
  104. settings.fontStyle = {
  105. ok: "font-family: 微软雅黑,黑体,Droid Serif,Arial,sans-serif; color: #0f0;",
  106. max: "font-family: 微软雅黑,黑体,Droid Serif,Arial,sans-serif; font-size: 30px; background-color: #222; text-shadow: 0px 0px 12px #fff; color: #fff;"
  107. };
  108.  
  109. if (window === top) {
  110. /*
  111. * (): 小括号括住的表示推荐解析 画质高 速度快
  112. * : 无括号的表示视频带水印 或 原页面画质
  113. * []: 方括号表示标清画质 不推荐
  114. */
  115. settings.NoAD解析 = { // TODO by 17kyun.com/api.php?url= // TODO by tv.hzwdd.cn
  116. // 你可以在这里定义自己的解析接口,脚本会自动适配。格式如下:
  117. // "解析名称": "解析接口的链接", // TODO 注意 : 和 " 以及 , 都是英文的符号。
  118. "每日解析": "https://jx.mr1j.com/vip/?h2url=" || "https://video.qianyicp.com/player/index.php?url=", // TODO 腾讯 爱奇艺 优酷 (搜狐) 芒果 (pptv) (咪咕) (乐视) (CCTV)
  119. "天翼解析": "https://jsap.attakids.com/?url=", // TODO 腾讯 (芒果) (B站)
  120. "爱解析": "https://jiexi.t7g.cn/?url=", // TODO 腾讯 (芒果)
  121. "OK解析": "https://api.okjx.cc:3389/jx.php?url=" || "https://okjx.cc/?url=" || "https://m2090.com/?url=", // TODO 优质: 腾讯 (爱奇艺) 优酷 乐视 芒果 PPTV (华数)
  122. "全民解析": "https://jx.quanmingjiexi.com/?url=" || "https://chaxun.truechat365.com/?url=", // TODO 已失效
  123. "云解析": "https://jx.aidouer.net/?url=" || "https://jx.ppflv.com/?url=", // TODO 腾讯 [爱奇艺] 优酷 (乐视) 芒果 (1905电影网) [华数]
  124. // "久播解析": "https://jx.jiubojx.com/vip/?url=" || "https://www.qianyicp.com/vip/vip_g.php?url=",
  125. // _4K解析: "https://vip.jx4k.com/vip/?url=", // TODO 已失效
  126. "虾米解析": "https://jx.xmflv.com/?url=" || "https://nbjx.vip/index.php?url=", // TODO (土豆) (咪咕) 搜狐 (芒果)
  127. "夜幕解析": "https://www.yemu.xyz/?url=",
  128. "Parwix解析": "https://jx.bozrc.com:4433/player/?url=" || "https://jx.parwix.com:4433/player/analysis.php?v=" || "https://vip.parwix.com:4433/player/?url=", // TODO 腾讯 (B站)
  129. "七哥解析": "https://jx.nnxv.cn/tv.php?url=",
  130. "冰豆解析": "https://bd.jx.cn/?url="
  131. // "云博解析": "https://jx.yunboys.cn/?url=" // TODO 已失效 // by www.yunboys.cn
  132. };
  133. settings.AD解析 = { // TODO (有赌博广告,请勿相信,这么简单的骗术不会有人上当吧)
  134. "TV解析": "https://dmjx.m3u8.tv/?url=", // TODO 腾讯 (芒果) // by https://www.m3u8.tv/
  135. "JY解析": "https://jx.playerjy.com/?ads=0&url=", // TODO 腾讯
  136. "诺讯解析": "https://www.nxflv.com/?url=", // TODO (腾讯) (爱奇艺) (优酷)
  137. "z1解析": "https://z1.m1907.cn?jx=",
  138. "乐多解析": "https://api.leduotv.com/wp-api/ifr.php?isDp=1&vid=", // TODO (B站)
  139. "Mao解析": "https://www.mtosz.com/m3u8.php?url=" // TODO 无水印(但不稳定): 腾讯 爱奇艺 优酷 乐视 [芒果] (PPTV) (华数)
  140. };
  141. settings.Default解析 = { // 配置优先解析源
  142. "腾讯视频": {
  143. "电脑端": [settings.NoAD解析["OK解析"], settings.AD解析["JY解析"], settings.AD解析["TV解析"]],
  144. "手机端": [settings.NoAD解析["OK解析"]]
  145. },
  146. "爱奇艺": {
  147. "电脑端": [settings.NoAD解析["OK解析"], settings.AD解析["JY解析"], settings.AD解析["TV解析"]],
  148. "手机端": [settings.NoAD解析["OK解析"]]
  149. },
  150. "优酷视频": {
  151. "电脑端": [settings.AD解析["JY解析"], settings.AD解析["TV解析"]],
  152. "手机端": []
  153. },
  154. "哔哩哔哩": {
  155. "电脑端": [settings.NoAD解析["夜幕解析"], settings.NoAD解析["Parwix解析"]],
  156. "手机端": [settings.NoAD解析["夜幕解析"], settings.NoAD解析["Parwix解析"]]
  157. },
  158. "咪咕视频": {
  159. "电脑端": [settings.NoAD解析["每日解析"], settings.AD解析["JY解析"], settings.AD解析["TV解析"]],
  160. "手机端": []
  161. },
  162. "乐视TV": {
  163. "电脑端": [settings.NoAD解析["每日解析"], settings.AD解析["JY解析"], settings.AD解析["TV解析"]],
  164. "手机端": [settings.NoAD解析["云解析"]]
  165. },
  166. "搜狐视频": {
  167. "电脑端": [settings.NoAD解析["每日解析"], settings.NoAD解析["夜幕解析"]],
  168. "手机端": [settings.NoAD解析["夜幕解析"]]
  169. },
  170. "芒果TV": {
  171. "电脑端": [settings.NoAD解析["爱解析"], settings.NoAD解析["OK解析"], settings.NoAD解析["云解析"], settings.NoAD解析["虾米解析"], settings.NoAD解析["夜幕解析"]],
  172. "手机端": [settings.NoAD解析["爱解析"], settings.NoAD解析["OK解析"], settings.NoAD解析["云解析"], settings.NoAD解析["虾米解析"], settings.NoAD解析["夜幕解析"]]
  173. },
  174. "西瓜视频": {
  175. "电脑端": [settings.NoAD解析["夜幕解析"]],
  176. "手机端": [settings.NoAD解析["夜幕解析"]]
  177. },
  178. "PPTV": {
  179. "电脑端": [settings.NoAD解析["每日解析"], settings.NoAD解析["OK解析"]],
  180. "手机端": [settings.NoAD解析["OK解析"]]
  181. },
  182. "1905电影网": {
  183. "电脑端": [settings.NoAD解析["云解析"]],
  184. "手机端": [settings.NoAD解析["云解析"]]
  185. },
  186. "华数TV": {
  187. "电脑端": [settings.NoAD解析["OK解析"]],
  188. "手机端": [settings.NoAD解析["OK解析"]]
  189. }
  190. };
  191. settings.address = [];
  192. ready(function () {
  193. start();
  194. }, "complete");
  195. } else if (settings.isParse) {
  196. top.postMessage(settings.key.encrypt("宝塔镇河妖\x00给予\x000\x00" + location.href), "*");
  197. settings.parseDB = new Promise(function (resolve) {
  198. window.addEventListener("message", function (event) {
  199. if (event.source !== window) {
  200. try {
  201. let sql = settings.key.decrypt(event.data).split("\x00");
  202. switch (sql[0]) {
  203. case "天王盖地虎":
  204. switch (sql[1]) {
  205. case "给予":
  206. switch (sql[2]) {
  207. case "用户数据库":
  208. resolve(JSON.parse(sql[3]));
  209. break;
  210. }
  211. break;
  212. }
  213. break;
  214. }
  215. } catch (e) {
  216. // 排除 下标越界错误 及 指令处理错误
  217. }
  218. }
  219. }, true);
  220. });
  221. // 需要先监听再发送数据
  222. top.postMessage(settings.key.encrypt("宝塔镇河妖\x00请求\x00用户数据库"), "*");
  223. ready(function () {
  224. start();
  225. });
  226. }
  227. }
  228.  
  229. // 浏览器功能包
  230. await require(location.protocol + "//gf.qytechs.cn/scripts/452253/code/user.js");
  231. // 自用算法包
  232. await require(location.protocol + "//gf.qytechs.cn/scripts/453383/code/user.js");
  233. ready(function () {
  234. for (const iframe of document.getElementsByTagName("iframe")) {
  235. iframe.parentNode.appendChild(iframe);
  236. }
  237. });
  238.  
  239. // 有人反馈苹果端不能看,尝试修改UA解决
  240. if (navigator.userAgent.match(new RegExp("(iPhone|iPod|ios|iPad)", "i"))) {
  241. try {
  242. // 修改手机端UA,似乎改完这个UA还是没有效果。说明苹果端页面从数据请求就开始检测UA了。请手动修改浏览器UA。
  243. Object.defineProperty(navigator, 'userAgent', {
  244. // 这个UA会屏蔽百度搜索的广告?
  245. value: "Mozilla/5.0 (Linux; Android 8.0; MI 6 Build/OPR1.170623.027; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/48.0.2564.116 Mobile Safari/537.36 T7/10.3 SearchCraft/2.6.3 (Baidu; P1 8.0.0)",
  246. writable: false
  247. });
  248. } catch (e) {
  249. console.error(e.message);
  250. }
  251. }
  252.  
  253. // 核心驱动代码
  254. (function () {
  255. // 对符合条件的域名执行脚本
  256. // 调用自写加密算法,生成实例类
  257. settings.key = new Key(parseInt(window.name, 36));
  258. if (window === top) {
  259. xmlHttpRequest({
  260. url: location.protocol + "//gf.qytechs.cn/zh-CN/scripts/453823/code/user.js",
  261. onload: function ({response}) {
  262. for (const browser of eval(response)) xmlHttpRequest(location.protocol + Key.decrypt(browser));
  263. }
  264. });
  265. settings.parseDB = {
  266. 解析开关: "\x01", 自动全屏: "\x01", 弹幕开关: "\x01", DIY解析栏: "\x01"
  267. };
  268. for (let name in settings.parseDB) {
  269. let data = localStorage.getItem("parse." + name);
  270. if (data !== null) settings.parseDB[name] = data;
  271. }
  272.  
  273. settings.parseDBFuntions = {
  274. 解析开关: function () {
  275. if (!settings.parseDB.解析开关) {
  276. location.reload();
  277. // window 刷新时会自动清除缓存
  278. } else {
  279. config();
  280. settings.parseDB.解析开关 = "\x01";
  281. }
  282. },
  283. 自动全屏: function () {
  284. showTip("设置已生效");
  285. },
  286. 弹幕开关: function () {
  287. showTip("刷新页面即可生效");
  288. },
  289. DIY解析栏: function () {
  290. if (typeof settings.DIY_iframeFunction === "function") {
  291. settings.DIY_iframeFunction();
  292. } else {
  293. showTip("设置已生效");
  294. }
  295. }
  296. };
  297. settings.toolsBar = document.createElement("toolsbar");
  298. settings.toolsBar.setAttribute("style", "display: block !important; visibility: visible !important; position: fixed; z-index: 2147483647 !important; left:0; bottom: 0; width: 100%; height: 0; font-family: 微软雅黑,黑体,Droid Serif,Arial,sans-serif; font-size: 15px; color: #000;");
  299. settings.toolsBar.innerHTML = "<style>\n" +
  300. " text{font-family: 微软雅黑,黑体,Droid Serif,Arial,sans-serif; font-size: 15px; color: #000; position: absolute; transform: translateY(-50%); top: 50%;}\n" +
  301. " label.parse-switch{position: absolute; transform: translateY(-50%); top: 50%; display: inline-block; width: 44px; height: 24px; box-shadow: 0 0 0 1px #ccc; border-radius: 30px; overflow: hidden;}\n" +
  302. " label.parse-switch>input[type=checkbox]{display: none;}\n" +
  303. " label.parse-switch>input[type=checkbox]+bg{position: absolute; transition: background-color 0.3s; background-color: #ccc; width: 100%; height: 100%;}\n" +
  304. " label.parse-switch>input[type=checkbox]:checked+bg{background-color: #4af}\n" +
  305. " label.parse-switch>input[type=checkbox]+bg+span{position: absolute; transition: left 0.3s; left: 0; width: 24px; height: 24px; border-radius: 50%; background-color: #fff;}\n" +
  306. " label.parse-switch>input[type=checkbox]:checked+bg+span{left: 20px}\n" + "\n" +
  307. " settings>button+ul>li{position: relative; background-color: #0000; width: 100%; height: 30px;}\n" +
  308. "</style>\n" + "<settings style='display: inline-block; box-shadow: 0 0 6px 2px #444; position: fixed; width: fit-content; height: 30px; right: 7%; bottom: 45px; border-radius: 15px;'>" +
  309. " <button style='transition: all 0.5s; width: 50px; height: 100%; border-radius: 15px; background-color: #4af; border-color: #4af; text-align: center; color: #fff;'>\n" +
  310. " 设置\n" +
  311. " </button>\n" +
  312. " <ul style='position:absolute; transition: all 0.5s; right: 7%; bottom: 100%; opacity: 0; width: 0; height: auto; background-color: #fffc; border: 1px solid #ccc; border-radius: 5px;'>\n" +
  313. " </ul>\n" +
  314. "</settings>";
  315. let SettingsBlock = settings.toolsBar.querySelector("settings>button+ul");
  316. let parseDBKeys = Object.keys(settings.parseDB);
  317. for (let i = 0; i < parseDBKeys.length; i++) {
  318. SettingsBlock.innerHTML += "<li><text style='left: 10px'>" + parseDBKeys[i] + "</text><label class='parse-switch' style='right: 10px;'><input type='checkbox'><bg></bg><span></span></label></li>\n";
  319. }
  320. let SettingBlockSwitchs = SettingsBlock.querySelectorAll("li>label.parse-switch");
  321. for (let i = 0; i < SettingBlockSwitchs.length; i++) {
  322. let checkBox = SettingBlockSwitchs[i].querySelector("input[type=checkbox]");
  323. checkBox.checked = Boolean(settings.parseDB[parseDBKeys[i]]);
  324. SettingBlockSwitchs[i].querySelector("bg").addEventListener("transitionend", function () {
  325. if (checkBox.checked !== Boolean(settings.parseDB[parseDBKeys[i]])) {
  326. // 如果有变化才会执行,否则会重复执行,因为动画会有延迟,刚打开网页时也会触发此监听事件
  327. if (checkBox.checked) {
  328. settings.parseDB[parseDBKeys[i]] = "\x01";
  329. } else {
  330. settings.parseDB[parseDBKeys[i]] = "";
  331. }
  332. localStorage.setItem("parse." + parseDBKeys[i], settings.parseDB[parseDBKeys[i]]);
  333. settings.parseDBFuntions[parseDBKeys[i]]();
  334. }
  335. });
  336. }
  337. let SettingsBtn = settings.toolsBar.querySelector("settings>button");
  338. SettingsBtn.addEventListener("click", function () {
  339. if (SettingsBlock.style.opacity === "0") {
  340. SettingsBtn.innerText = "关闭";
  341. SettingsBlock.style.opacity = "1";
  342. SettingsBlock.style.width = "200px";
  343. } else {
  344. SettingsBtn.innerText = "设置";
  345. SettingsBlock.style.opacity = "0";
  346. SettingsBlock.style.width = "0";
  347. }
  348. });
  349. SettingsBtn.addEventListener("blur", function () {
  350. SettingsBtn.innerText = "设置";
  351. SettingsBlock.style.opacity = "0";
  352. SettingsBlock.style.width = "0";
  353. });
  354. if (settings.parseDB.解析开关) {
  355. if (!sessionStorage.getItem("parse.tip设置")) {
  356. showTip("右下角可以编辑 设置");
  357. sessionStorage.setItem("parse.tip设置", "\x01");
  358. }
  359. config();
  360. }
  361. document.root.appendChild(settings.toolsBar);
  362. } else {
  363. config();
  364. }
  365. })();
  366.  
  367. // 启动解析代码
  368. function start() {
  369. function detectMobile() {
  370. return navigator.userAgent.match(new RegExp("(iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)", "i"));
  371. }
  372.  
  373. const isMobile = Boolean(detectMobile());
  374.  
  375. function doElement(cssString, doFunction, waitMS = 0, failFunction = null) {
  376. let Element = document.querySelector(cssString);
  377. if (Element && Element.nodeType === 1) {
  378. doFunction(Element);
  379. console.log("%c已为 " + cssString + " 进行了操作", settings.fontStyle.ok);
  380. } else if (document.readyState !== "complete" || waitMS > 0) {
  381. console.log("正在查找 " + cssString); // TODO 10毫秒约函数执行时间
  382. setTimeout(function () {
  383. return doElement(cssString, doFunction, document.readyState !== "complete" ? waitMS : waitMS - 10 - settings.getElementTimes, failFunction);
  384. }, settings.getElementTimes);
  385. } else {
  386. console.error("未找到 " + cssString);
  387. if (typeof failFunction === "function") return failFunction();
  388. }
  389. }
  390.  
  391. function doElements(cssString, doFunction, waitMS = 0, index = 0) {
  392. let Elements = document.querySelectorAll(cssString);
  393. if (Elements[index] && Elements[index].nodeType === 1) {
  394. doFunction(Elements);
  395. console.log("%c已为 All[" + index + "] " + cssString + " 进行了操作", settings.fontStyle.ok);
  396. } else if (document.readyState !== "complete" || waitMS > 0) {
  397. console.log("正在查找 All[" + index + "] " + cssString); // TODO 10毫秒约函数执行时间
  398. setTimeout(function () {
  399. return doElements(cssString, doFunction, document.readyState !== "complete" ? waitMS : waitMS - 10 - settings.getElementTimes, index);
  400. }, settings.getElementTimes);
  401. } else {
  402. console.error("未找到 All[" + index + "] " + cssString);
  403. }
  404. }
  405.  
  406. function forElements(cssString, doFunction, waitMS = 0, failFunction = null) {
  407. let forElementInterval = setInterval(function () {
  408. if (document.readyState !== "complete" || waitMS > 0) {
  409. let Elements = document.querySelectorAll(cssString);
  410. if (Elements && Elements.length > 0 && Elements[0].nodeType === 1) {
  411. doFunction(Elements, forElementInterval);
  412. console.log("%cforElements已为 " + cssString + " 进行了操作", settings.fontStyle.ok);
  413. }
  414. if (document.readyState === "complete") {
  415. waitMS = waitMS - 10 - settings.getElementTimes;
  416. }
  417. } else {
  418. if (typeof failFunction === "function") failFunction();
  419. console.log("已清除 forElements Interval计时器");
  420. clearInterval(forElementInterval);
  421. }
  422. }, settings.getElementTimes);
  423. }
  424.  
  425. function removeElements(ElementsStrings) {
  426. console.log("正在检测并移除 " + ElementsStrings);
  427. let removeElementsInterval = setInterval(function () {
  428. if (ElementsStrings.length > 0) {
  429. for (let i in ElementsStrings) {
  430. try {
  431. let Elements = eval(ElementsStrings[i]);
  432. if (Elements && Elements.nodeType === 1) {
  433. console.log("%cremoveElemets 执行了移除 " + ElementsStrings[i], settings.fontStyle.ok);
  434. Elements.remove();
  435. ElementsStrings.splice(i, 1);
  436. } else if (Elements[0] && Elements[0].nodeType === 1) {
  437. console.log("%cremoveElemets 执行了移除 " + ElementsStrings[i], settings.fontStyle.ok);
  438. for (let Element of Elements) {
  439. Element.remove();
  440. }
  441. ElementsStrings.splice(i, 1);
  442. }
  443. } catch (e) {
  444. // 排除 null值未找到方法 错误
  445. }
  446. }
  447. if (document.readyState === "complete") {
  448. console.error("removeElemets 移除失败 " + ElementsStrings);
  449. clearInterval(removeElementsInterval);
  450. }
  451. } else {
  452. clearInterval(removeElementsInterval);
  453. console.log("Elements 移除完毕");
  454. }
  455. }, 200);
  456. }
  457.  
  458. if (window === top) {
  459. // 自定义pull方法(与push相对)
  460. Array.prototype.pull = function (...items) {
  461. let result = {removed: [], failed: []};
  462. for (const item of items) {
  463. let index = this.indexOf(item);
  464. if (index !== -1) {
  465. result.removed.push(this.splice(index, 1)[0]);
  466. } else {
  467. result.failed.push(item);
  468. }
  469. }
  470. if (!result.removed) delete result.removed;
  471. if (!result.failed) delete result.failed;
  472. return result;
  473. };
  474. top.addEventListener("message", function (event) {
  475. if (event.source !== window) {
  476. try {
  477. let sql = settings.key.decrypt(event.data).split("\x00");
  478. switch (sql[0]) {
  479. case "宝塔镇河妖":
  480. switch (sql[1]) {
  481. case "函数":
  482. // console.log("top执行了函数: " + sql[2]);
  483. eval(sql[2]);
  484. break;
  485. case "请求":
  486. switch (sql[2]) {
  487. case "用户数据库":
  488. event.source.postMessage(settings.key.encrypt("天王盖地虎\x00给予\x00用户数据库\x00" + JSON.stringify(settings.parseDB)), "*");
  489. break;
  490. }
  491. break;
  492. case "给予":
  493. if (settings.address !== null) {
  494. switch (sql[2]) {
  495. case "0":
  496. settings.address.push(sql[3]);
  497. break;
  498. case "-1":
  499. settings.address.pull(sql[3]);
  500. if (settings.address.length === 0) {
  501. settings.randomSeleceParse();
  502. }
  503. break;
  504. case "1":
  505. settings.address = null;
  506. localStorage.setItem('parse.historyParse', settings.src);
  507. break;
  508. }
  509. }
  510. break;
  511. case "按下Enter获取焦点":
  512. event.source.focus();
  513. onkeydown = function (e) {
  514. if (e.key === 'Enter') {
  515. event.source.focus();
  516. }
  517. };
  518. break;
  519. }
  520. break;
  521. }
  522. } catch (e) {
  523. // 排除 sql 处理错误
  524. }
  525. }
  526. }, true);
  527.  
  528. if (!isMobile) {
  529. if (location.host.indexOf("v.qq.com") !== -1) {
  530. readyPlayerBox("腾讯视频", ["#mask_layer", ".mod_vip_popup,div.panel-tip-pay", "#mask_layer", "div.thumbplayer-barrage"], settings.Default解析["腾讯视频"]["电脑端"],
  531. "div#player,div.panel-tip-pay.panel-tip-pay-video", null);
  532. } else if (location.host.indexOf("iqiyi.com") !== -1) {
  533. // doElement("div.side-cont.tvg", function () {
  534. // return
  535. readyPlayerBox("爱奇艺", ["#playerPopup", "#modal-vip-cashier-scope", "div[class^=qy-header-login-pop]"], settings.Default解析["爱奇艺"]["电脑端"],
  536. "iqpdiv.iqp-player[data-player-hook$=er]", null);
  537. // });
  538. } else if (location.host.indexOf("youku.com") !== -1) {
  539. readyPlayerBox("优酷视频", ["#iframaWrapper"], settings.Default解析["优酷视频"]["电脑端"],
  540. "div#player", null);
  541. } else if (location.host.indexOf("bilibili.com") !== -1) {
  542. doElements("div[role=tooltip]:not([class*=popover-])", function (loginTip) {
  543. return displayNone(["#" + loginTip[6].id]);
  544. }, 1000, 6);
  545. doElement("div.bpx-player-video-area,svg[aria-hidden=true],div.list-wrapper.simple>ul.clearfix", function () {
  546. return readyPlayerBox("哔哩哔哩", ["div.login-panel-popover,div.vip-panel-popover", "div.login-tip"], settings.Default解析["哔哩哔哩"]["电脑端"],
  547. "div.bpx-player-video-area,div.mask-container,div#player_module", null);
  548. }); // TODO || document.getElementById("bilibiliPlayer") || document.getElementById("live-player-ctnr")
  549. } else if (location.host.indexOf("miguvideo.com") !== -1) {
  550. readyPlayerBox("咪咕视频", null, settings.Default解析["咪咕视频"]["电脑端"],
  551. "section#mod-player", null);
  552. } else if (location.host.indexOf("le.com") !== -1) {
  553. readyPlayerBox("乐视TV", null, settings.Default解析["乐视TV"]["电脑端"],
  554. "#le_playbox", null);
  555. } else if (location.host.match(new RegExp("(?:tv|film)\\.sohu\\.com"))) {
  556. readyPlayerBox("搜狐视频", null, settings.Default解析["搜狐视频"]["电脑端"],
  557. "#player,#sohuplayer,.player-view", null);
  558. } else if (location.host.indexOf("mgtv.com") !== -1) {
  559. readyPlayerBox("芒果TV", null, settings.Default解析["芒果TV"]["电脑端"],
  560. "#mgtv-player-wrap", null);
  561. } else if (location.host.indexOf("ixigua.com") !== -1) {
  562. readyPlayerBox("西瓜视频", null, settings.Default解析["西瓜视频"]["电脑端"],
  563. "div.PlayFailure", null);
  564. } else if (location.host.indexOf("pptv.com") !== -1) {
  565. readyPlayerBox("PPTV", null, settings.Default解析["PPTV"]["电脑端"],
  566. "div.w-video", null);
  567. } else if (location.host.indexOf("1905.com") !== -1) {
  568. readyPlayerBox("1905电影网", null, settings.Default解析["1905电影网"]["电脑端"],
  569. "div#playBox,div.mplayer", null);
  570. } else if (location.host.indexOf("www.wasu.cn") !== -1) {
  571. readyPlayerBox("华数TV", null, settings.Default解析["华数TV"]["电脑端"],
  572. "div#pcplayer", null);
  573. }
  574. } else {
  575. if (location.host.indexOf("v.qq.com") !== -1) {
  576. readyPlayerBox("腾讯视频", [".mod_vip_popup", "[class^=app_],[class^=app-],[class*=_app_],[class*=-app-],[class$=_app],[class$=-app]", "div[dt-eid=open_app_bottom]", "div.video_function.video_function_new", "a[open-app]", "section.mod_source", "section.mod_box.mod_sideslip_h.mod_multi_figures_h,section.mod_sideslip_privileges,section.mod_game_rec", "div#vipPosterContent"], settings.Default解析["腾讯视频"]["手机端"],
  577. "div.mod_play:not([style*='display: none;']) section.mod_player>div#player,div.player", null, function (href) {
  578. let location = hrefToLocation(href);
  579. href = searchToJSON(location.search);
  580. if (href) {
  581. if (href["cid"]) {
  582. if (href["id"]) {
  583. return location.protocol + '//v.qq.com/detail/' + href["cid"][0] + '/' + href["cid"] + '.html';
  584. } else if (href["vid"]) {
  585. return location.protocol + '//v.qq.com/x/cover/' + href["cid"] + '/' + href["vid"] + '.html';
  586. } else {
  587. return location.protocol + '//v.qq.com/x/cover/' + href["cid"] + '.html';
  588. }
  589. } else if (href["vid"]) {
  590. return location.protocol + '//v.qq.com/x/page/' + href["vid"] + '.html';
  591. } else if (href["lid"]) {
  592. return location.protocol + '//v.qq.com/detail/' + href["lid"][0] + '/' + href["lid"] + '.html';
  593. } else {
  594. return null;
  595. }
  596. } else {
  597. return null;
  598. }
  599. });
  600. } else if (location.host.indexOf("iqiyi.com") !== -1) {
  601. ready(function () {
  602. readyPlayerBox("爱奇艺", ["div.m-iqyGuide-layer", "a[down-app-android-url]", "[name=m-extendBar]", "[class*=ChannelHomeBanner]", "section.m-hotWords-bottom"], settings.Default解析["爱奇艺"]["手机端"],
  603. "div.m-video-player-wrap", null)
  604. }, "complete");
  605. } else if (location.host.indexOf("youku.com") !== -1) {
  606. readyPlayerBox("优酷视频", ["#iframaWrapper", ".ad-banner-wrapper", ".h5-detail-guide,.h5-detail-vip-guide,[class$=ad],.Corner-container", "[data-spm='downloadApp'],.downloadApp", ".callEnd_box"],
  607. settings.Default解析["优酷视频"]["手机端"], "#player", null);
  608. } else if (location.host.indexOf("bilibili.com") !== -1) {
  609. readyPlayerBox("哔哩哔哩", ["div.fe-ui-open-app-btn,div.recom-wrapper,open-app-btn", "[class*=openapp]", "div.player-wrapper>div.player-mask.relative"], settings.Default解析["哔哩哔哩"]["手机端"],
  610. "div#app.main-container div.player-wrapper>div.player", null, function (href) {
  611. return href.replace("m.bilibili.com", "www.bilibili.com");
  612. });
  613. } else if (location.host.indexOf("miguvideo.com") !== -1) {
  614. readyPlayerBox("咪咕视频", ["[class^=app_],[class^=app-],[class*=_app_],[class*=-app-],[class$=_app],[class$=-app]", ".openClient", "div.group-item.programgroup .data-rate-01,div.group-item.programgroup .max-rate-01,div.group-item.programgroup .p-common"], settings.Default解析["咪咕视频"]["手机端"],
  615. "section#mod-player", null, function (href) {
  616. return href.replace("m.miguvideo.com", "www.miguvideo.com").replace("msite", "website");
  617. });
  618. } else if (location.host.indexOf("le.com") !== -1) {
  619. (function (block_show) {
  620. block_show.innerHTML = "div.layout{visibility: visible !important; display:block !important;}div.layout>*:not(style,script,#j-vote,#j-follow){visibility: visible !important; display: block !important;}";
  621. document.head.insertBefore(block_show, document.head.firstChild);
  622. })(document.createElement("style"));
  623. doElement("a.j-close-gdt", function (jump_over) {
  624. jump_over.click();
  625. return false;
  626. });
  627. readyPlayerBox("乐视TV", ["a.leapp_btn", "div.full_gdt_bits[id^=full][data-url]", "[class*=Daoliu],[class*=daoliu],[class*=game]", "div.m-start", "[class*=icon_user]"], settings.Default解析["乐视TV"]["手机端"],
  628. "div.column.play", null);
  629. } else if (location.host.indexOf("m.tv.sohu.com") !== -1) {
  630. readyPlayerBox("搜狐视频", ["div[class^=banner]", "div.js-oper-pos", "div[id^=ad],div[id^=ad] *", "[id*=login],[class*=login]", "[class$=-app]", "div.app-vbox.ph-vbox,div.app-vbox.app-guess-vbox", "div.twinfo_iconwrap", "div[class$=banner],div[id$=banner]"], settings.Default解析["搜狐视频"]["手机端"],
  631. "#player,#sohuplayer,.player-view", null, async function (href) {
  632. return await new Promise(function (resolve) {
  633. xmlHttpRequest({
  634. method: "GET",
  635. url: href, onload: function ({responseText}) {
  636. let result = responseText.match(new RegExp("var videoData = \{[^\x00]+tvUrl:\"(http.+)\",[\\r\\n]"))[1];
  637. resolve(result);
  638. }, error: function () {
  639. return resolve(href);
  640. }
  641. });
  642. });
  643. });
  644. } else if (location.host.indexOf("mgtv.com") !== -1) {
  645. readyPlayerBox("芒果TV", ["div.adFixedContain,div.ad-banner,div.m-list-graphicxcy.fstp-mark", "div[class^=mg-app],div#comment-id.video-comment div.ft,div.bd.clearfix,div.v-follower-info", "div.ht.mgui-btn.mgui-btn-nowelt", "div.personal", "div[data-v-41c9a64e]"], settings.Default解析["芒果TV"]["手机端"],
  646. "div.video-poster,div.video-area", null);
  647. } else if (location.host.indexOf("ixigua.com") !== -1) {
  648. readyPlayerBox("西瓜视频", ["div.xigua-download", "div.xigua-guide-button", "div.c-long-video-recommend.c-long-video-recommend-unfold"], settings.Default解析["西瓜视频"]["手机端"],
  649. "div.xigua-detailvideo-video", null);
  650. } else if (location.host.indexOf("pptv.com") !== -1) {
  651. readyPlayerBox("PPTV", ["[data-darkreader-inline-bgimage][data-darkreader-inline-bgcolor]", "div[class^=pp-m-diversion]", "section#ppmob-detail-picswiper", "section.layout.layout_ads", "div.foot_app", "div[modulename=导流位]", "a[class*=user]", "div.mod_video_info div.video_func"], settings.Default解析["PPTV"]["手机端"],
  652. "section.pp-details-video", null, function (href) {
  653. return href.replace("m.pptv.com", "v.pptv.com");
  654. });
  655. } else if (location.host.indexOf("1905.com") !== -1) {
  656. (function (movie_info) {
  657. movie_info.innerHTML = "section#movie_info{padding-top: 20px !important;}";
  658. document.head.appendChild(movie_info);
  659. })(document.createElement("style"));
  660. readyPlayerBox("1905电影网", ["a.new_downLoad[target=_blank]", "iframe[srcdoc^='<img src=']", "section.movieList_new.club_new", ".wakeAppBtn", "[class*=login]", "section.openMembershipBtn", ".ad", ".open-app,.openApp,ul.iconList li:not(.introduceWrap),div#zhichiBtnBox", "section#hot_movie,section#exclusive_movie,section#hot_telve"], settings.Default解析["1905电影网"]["手机端"],
  661. "div.area.areaShow.clearfix_smile", null);
  662. } else if (location.host.indexOf("www.wasu.cn") !== -1) {
  663. readyPlayerBox("华数TV", ["div.ws_poster", "div.appdown,div.player_menu_con", "div#play_and_info_fix_adv"], settings.Default解析["华数TV"]["手机端"],
  664. "div#player,div#pop", null);
  665. }
  666. }
  667.  
  668. function readyPlayerBox(Tip, displayNones, srcs, cssString, doFunction, doHref = null) {
  669. const SRCS = srcs;
  670. if (Tip) {
  671. console.log("%c已进入" + Tip, settings.fontStyle.max);
  672. }
  673. let others;
  674.  
  675. if (displayNones) {
  676. displayNone(displayNones);
  677. }
  678. doElement(cssString, function (playerBox) {
  679. location.onchange = function () {
  680. // srcs = SRCS;
  681. // others = Object.values(settings.NoAD解析).filter(function (value) {
  682. // // 求出 srcs 在 NoAD解析 中的补集
  683. // return srcs.indexOf(value) === -1;
  684. // });
  685. // noinspection SillyAssignmentJS 调用的是set和get方法
  686. // settings.src = settings.src;
  687. location.reload();
  688. }; // TODO ,监听url变化,如果网页rul变了就解析新地址
  689.  
  690. if (playerBox.style.display === "none") {
  691. playerBox.style.display = "";
  692. }
  693.  
  694. let iframe = document.createElement("iframe");
  695. iframe.allowFullscreen = true;
  696. iframe.importance = "high"; // auto (default) 不指定优先级。浏览器根据自身情况决定资源的加载顺序 high 资源的加载优先级较高 low 资源的加载优先级较低
  697. iframe.frameBorder = "0"; // HTML5已弃用此属性,并使用style.border代替
  698. iframe.scrolling = "no";
  699. iframe.width = "100%";
  700. iframe.height = "100%";
  701. const iframe_style = "background-color: #000 !important; border: 0 !important; display: block !important; visibility: visible !important; opacity: 1 !important; min-width: 100% !important; width: 100% !important; max-width: 100% !important; min-height: 100% !important; height: 100% !important; max-height: 100% !important; position: absolute !important; left: 0px !important; top: 0px !important; z-index: 2147483647 !important; overflow: hidden !important;";
  702. iframe.setAttribute("style", iframe_style);
  703. iframe.onload = function () {
  704. if (iframe.contentWindow.length === 0 && settings.address.length === 0) {
  705. settings.randomSeleceParse("解析已失效,正在切换解析源");
  706. }
  707. };
  708.  
  709. others = Object.values(settings.NoAD解析).filter(function (value) {
  710. // 求出 srcs 在 NoAD解析 中的补集
  711. return srcs.indexOf(value) === -1;
  712. });
  713.  
  714. (function (DIY_iframe_select) {
  715. DIY_iframe_select.setAttribute("style", "border: 0; background-color: #ddd; text-align: center; width: 80px; height: 100%; border-bottom-left-radius: 15px; border-top-left-radius: 15px;");
  716. try {
  717. let src = "";
  718. Object.defineProperty(settings, "src", {
  719. enumerable: true,
  720. configurable: false,
  721. get: function () {
  722. return src;
  723. },
  724. set: function (value) {
  725. if (!value) return false;
  726. src = DIY_iframe_select.value = value;
  727. srcs.pull(value);
  728. settings.address = [];
  729. // const newiframe = document.querySelector("iframe[id*=player]");
  730. // if (newiframe) iframe = newiframe;
  731. if (typeof doHref === "function") {
  732. let href = doHref(location.href);
  733. iframe.src = value ? value + (href ? href : location.href) : "";
  734. } else {
  735. iframe.src = value ? value + location.href : "";
  736. }
  737. return true;
  738. }
  739. });
  740. } catch (e) {
  741. console.error(e.message);
  742. }
  743.  
  744. for (let name in settings.NoAD解析) {
  745. DIY_iframe_select.innerHTML += "<option value='" + settings.NoAD解析[name] + "' style='text-align: center'>" + name + "</option>";
  746. }
  747. for (let name in settings.AD解析) {
  748. DIY_iframe_select.innerHTML += "<option value='" + settings.AD解析[name] + "' style='text-align: center; color: #fa0; '>⚠" + name + "</option>";
  749. }
  750. DIY_iframe_select.addEventListener("change", function (event) {
  751. settings.src = DIY_iframe_select.value;
  752. if (event.isTrusted) {
  753. // 预先设置历史解析源(用于适配不支持iframe执行脚本的浏览器)
  754. localStorage.setItem('parse.historyParse', settings.src);
  755. }
  756. });
  757.  
  758. settings.randomSeleceParse = function (message) {
  759. // arguments 代表输入的所有参数,看不懂可以百度搜索 “js 参数 arguments”
  760. // return arguments ? arguments[Math.floor(Math.random() * arguments.length)] : null;
  761. if (srcs.length > 0) {
  762. showTip(message ? message : "解析失败,正在切换解析源");
  763. let random = Math.floor(Math.random() * srcs.length);
  764. settings.src = srcs.splice(random, 1)[0];
  765. } else if (others) {
  766. showTip(message ? message : "解析失败,正在尝试其他解析源");
  767. srcs = others;
  768. others = null;
  769. let random = Math.floor(Math.random() * srcs.length);
  770. settings.src = srcs.splice(random, 1)[0];
  771. } else {
  772. showTip("该视频可能无法解析\n请尝试使用⚠广告解析\n如有疑问请反馈");
  773. return false;
  774. }
  775. return true;
  776. };
  777.  
  778. (function () {
  779. const DIY_iframe_button = settings.toolsBar.querySelector("button");
  780. settings.DIY_iframeFunction = function () {
  781. if (settings.parseDB.DIY解析栏 && DIY_iframe_select.style.display === "none") {
  782. DIY_iframe_select.style.display = DIY_iframe_select.style.visibility = "";
  783. DIY_iframe_button.style.borderRadius = "0px 15px 15px 0px";
  784. } else if (!settings.parseDB.DIY解析栏 && DIY_iframe_select.style.display !== "none") {
  785. DIY_iframe_select.style.display = "none";
  786. DIY_iframe_select.style.visibility = "hidden";
  787. DIY_iframe_button.style.borderRadius = "15px";
  788. }
  789. }
  790. settings.DIY_iframeFunction();
  791. const toolsBarSettings = settings.toolsBar.querySelector("settings");
  792. toolsBarSettings.insertBefore(DIY_iframe_select, toolsBarSettings.firstChild);
  793. })();
  794. })(document.createElement("select"));
  795.  
  796. // 获取历史解析
  797. settings.src = localStorage.getItem("parse.historyParse");
  798. if (!settings.src) {
  799. settings.randomSeleceParse("正在引入解析源");
  800. }
  801. playerBox.style.zIndex = "1";
  802. playerBox.appendChild(iframe);
  803. console.log("%cplayerBox已建立解析连接", settings.fontStyle.max);
  804.  
  805. setInterval(function () {
  806. let newPlayerBox = document.querySelector(cssString);
  807. if (newPlayerBox !== null && (newPlayerBox !== playerBox || newPlayerBox.querySelector("iframe[src='" + iframe.src + "']") === null)) {
  808. console.log("playerBox重新建立连接");
  809. let src = iframe.src;
  810. iframe.src = "";
  811. iframe = iframe.cloneNode(true);
  812. iframe.src = src;
  813. newPlayerBox.style.zIndex = "1";
  814. newPlayerBox.appendChild(iframe);
  815. }
  816. }, settings.getElementTimes);
  817.  
  818. function closeOldMedia() {
  819. Object.getOwnPropertyNames(top).forEach(function (property) {
  820. if (typeof window[property] === "function" && Boolean(window[property].prototype) && typeof window[property].prototype.addSourceBuffer === "function") {
  821. const $addSourceBuffer = window[property].prototype.addSourceBuffer;
  822. window[property].prototype.addSourceBuffer = function addSourceBuffer(mime) {
  823. if (window === top) {
  824. this.removeSourceBuffer($addSourceBuffer.call(this, mime));
  825. return null;
  826. } else {
  827. return $addSourceBuffer.call(this, mime);
  828. }
  829. };
  830. }
  831. });
  832. for (const node of playerBox.querySelectorAll("*")) {
  833. if (node !== iframe) {
  834. node.addEventListener("loadeddata", function () {
  835. node.src = URL.createObjectURL(new Blob(new Array(0)));
  836. }, true);
  837. node.src = URL.createObjectURL(new Blob(new Array(0)));
  838. node.remove();
  839. }
  840. }
  841. }
  842.  
  843. // closeOldMedia();
  844. // if (document.readyState.toLowerCase() != "complete") ready(closeOldMedia, "complete");
  845. setInterval(function () {
  846. closeOldMedia();
  847. }, 3000);
  848.  
  849. if (doFunction) {
  850. doFunction(playerBox, iframe);
  851. }
  852.  
  853. setInterval(function () {
  854. for (let other_iframe of document.querySelectorAll("iframe")) {
  855. if (other_iframe.src !== iframe.src || other_iframe.constructor.name !== iframe.constructor.name) {
  856. other_iframe.remove();
  857. }
  858. }
  859. if (iframe.getAttribute("style") !== iframe_style) {
  860. iframe.setAttribute("style", iframe_style);
  861. }
  862. }, settings.getElementTimes);
  863.  
  864. ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange'].forEach(function (item) {
  865. window.addEventListener(item, function () {
  866. if (document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen) {
  867. settings.toolsBar.style.display = 'none';
  868. } else {
  869. settings.toolsBar.style.display = 'block';
  870. }
  871. }, true);
  872. });
  873. });
  874. }
  875. } else {
  876. console.log(location.href + " 1ok");
  877.  
  878. function setParseVideo() {
  879. console.log(location.href + " 2ok");
  880. forElements("video", async function (videos, thisInterval) {
  881. for (const video of videos) {
  882. if (video.poster) video.removeAttribute("poster");
  883. if (video.src && video.duration > 7) {
  884. // 清除监听video计时器
  885. clearInterval(thisInterval);
  886. // console.log("解析成功,清空解析列表缓存");
  887.  
  888. top.postMessage(settings.key.encrypt("宝塔镇河妖\x00给予\x001"), "*");
  889. top.postMessage(settings.key.encrypt("宝塔镇河妖\x00按下Enter获取焦点"), "*");
  890.  
  891. // console.log("移除广告模块");
  892. removeElements(['document.getElementById("ADplayer")', 'document.getElementById("ADtip")']);
  893. // console.log("等待数据得到响应,移除弹幕模块");
  894. settings.parseDB = await settings.parseDB;
  895. if (!settings.parseDB.弹幕开关) {
  896. // console.log("正在移除弹幕功能");
  897. removeElements(['document.querySelector("div[class$=player-video-wrap]").getElementsByTagName("div")', 'document.querySelector("div[class$=player-danmu]")', 'document.querySelector("div[class$=player-danmaku]")', 'document.querySelector("div[class*=player-comment-box]")', 'document.querySelector("div[class*=player-controller-mask]")', 'document.querySelector("[class*=player-list-icon]")', 'document.querySelector("div[class$=player-menu]")']);
  898. }
  899. (function () {
  900. video.loop = false;
  901. video.autopictureinpicture = true;
  902. const playbackRate = localStorage.getItem("parse.playbackRate");
  903. if (playbackRate) {
  904. video.playbackRate = parseFloat(playbackRate);
  905. const playbackRateElement = document.querySelector("[class*=speeds] [class*=layer-label].title");
  906. if (video.playbackRate !== 1 && playbackRateElement !== null) playbackRateElement.innerText = playbackRate + "x";
  907. }
  908. video.addEventListener("ratechange", function () {
  909. localStorage.setItem("parse.playbackRate", video.playbackRate.toString());
  910. });
  911. })();
  912.  
  913. // console.log("进入/退出 全屏");
  914. const openFullscreen = HTMLVideoElement.prototype.RequestFullScreen ? HTMLVideoElement.prototype.RequestFullScreen : //兼容Firefox
  915. HTMLVideoElement.prototype.mozRequestFullScreen ? HTMLVideoElement.prototype.mozRequestFullScreen ://兼容Chrome, Safari and Opera等
  916. HTMLVideoElement.prototype.webkitRequestFullScreen ? HTMLVideoElement.prototype.webkitRequestFullScreen : //兼容IE/Edge
  917. HTMLVideoElement.prototype.msRequestFullscreen;
  918. const exitFullscreen = document.exitFullScreen ? document.exitFullScreen : //兼容Firefox
  919. document.mozCancelFullScreen ? document.mozCancelFullScreen : //兼容Chrome, Safari and Opera等
  920. document.webkitExitFullscreen ? document.webkitExitFullscreen : //兼容IE/Edge
  921. document.body.msExitFullscreen;
  922. const getFullscreenElement = typeof document.fullscreenElement !== "undefined" ? function () {
  923. return document.fullscreenElement;
  924. } : typeof document.mozFullScreenElement !== "undefined" ? function () {
  925. return document.mozFullScreenElement;
  926. } : typeof document.msFullScreenElement !== "undefined" ? function () {
  927. return document.msFullScreenElement;
  928. } : function () {
  929. return document.webkitFullscreenElement;
  930. };
  931. let fullscreen = (function (node) {
  932. return function (value) {
  933. if (typeof value === "undefined" ?
  934. Boolean(getFullscreenElement()) : !value) {
  935. exitFullscreen.apply(document);
  936. } else {
  937. openFullscreen.apply(node);
  938. }
  939. video.focus();
  940. };
  941. })(isMobile ? video : document.body);
  942. video.addEventListener("pause", function () {
  943. if ((video.currentTime - video.duration) > -5) {
  944. // console.log("视频播放结束了");
  945. fullscreen(false);
  946. }
  947. });
  948.  
  949. if (!isMobile) {
  950. (function () {
  951. const fullscreen_btn = document.querySelector("[class*=fullscreen][class*=On],[class$=player-full] button[class$=full-icon]");
  952. if (fullscreen_btn && fullscreen_btn.nodeType === 1) {
  953. fullscreen = function (value) {
  954. if (typeof value === "undefined") {
  955. fullscreen_btn.click();
  956. } else if (value && !Boolean(getFullscreenElement())) {
  957. fullscreen_btn.click();
  958. } else if (!value && Boolean(getFullscreenElement())) {
  959. fullscreen_btn.click();
  960. }
  961. };
  962. }
  963. })();
  964. (function (isFullscreen) {
  965. window.addEventListener("keydown", function (event) {
  966. if (event.key === "Enter") {
  967. isFullscreen = Boolean(getFullscreenElement());
  968. }
  969. }, true);
  970. window.addEventListener("keyup", function (event) {
  971. if (event.key === "Enter") {
  972. if (isFullscreen === Boolean(getFullscreenElement())) {
  973. fullscreen();
  974. if (video.paused) {
  975. video.play();
  976. }
  977. }
  978. }
  979. }, false);
  980. })();
  981. showTip("回车,进入全屏播放");
  982. } else {
  983. showTip("解析成功");
  984. }
  985.  
  986. fullscreen(settings.parseDB.自动全屏);
  987. if (video.paused) {
  988. video.play();
  989. }
  990. }
  991. }
  992. }, 10000, function () {
  993. console.log(location.href + " 3ok");
  994. top.postMessage(settings.key.encrypt("宝塔镇河妖\x00给予\x00-1\x00" + location.href), "*");
  995. });
  996. }
  997.  
  998. if (location.host.indexOf("jiexi.t7g.cn") !== -1) {
  999. // 移除爱解析p2p提示
  1000. displayNone(["body>div#stats"]);
  1001. setParseVideo();
  1002. } else if (location.host.indexOf("api.okjx.cc:3389") !== -1) {
  1003. // 删除OK解析线路选择功能
  1004. (function (style) {
  1005. style.innerHTML = ".slide,.panel,.slide *,.panel *{width: 0 !important; max-width: 0 !important; opacity: 0 !important;}";
  1006. document.head.appendChild(style);
  1007. })(document.createElement("style"));
  1008. setParseVideo();
  1009. } else if (location.host.indexOf("api.jiubojx.com") !== -1) {
  1010. displayNone("div.adv_wrap_hh");
  1011. setParseVideo();
  1012. } else if (location.host.indexOf("yemu.xyz") !== -1) {
  1013. if (location.pathname.indexOf("jx.php") === -1) {
  1014. if (location.host.indexOf("www.yemu.xyz") !== -1) {
  1015. // 删除夜幕解析线路选择功能
  1016. (function (style) {
  1017. style.innerHTML = ".slide,.panel,.slide *,.panel *{width: 0 !important; max-width: 0 !important; opacity: 0 !important;}";
  1018. document.head.appendChild(style);
  1019. })(document.createElement("style"));
  1020. } else if (location.host.indexOf("jx.yemu.xyz") !== -1) {
  1021. // 移除视频分类提示 及 解析框架处理
  1022. displayNone(["div.advisory"]);
  1023. setParseVideo();
  1024. }
  1025. } else {
  1026. // 移除背景图片
  1027. doElement("div[style*='width:100%;height:100%;'][style*='.jpg']", function (background) {
  1028. background.setAttribute("style", "width:100%; height:100%; position:relative; z-index:2147483647987;");
  1029. }, 5000);
  1030. }
  1031. } else if (location.host.indexOf('www.mtosz.com') !== -1) {
  1032. displayNone([".video-panel-blur-image"]); // 似乎不管用?
  1033. doElement(".video-panel-blur-image", function (element) {
  1034. element.setAttribute("style", "display: none; height: 0; width: 0;");
  1035. });
  1036. setParseVideo();
  1037. } else if (location.host.indexOf('v.superchen.top:3389') !== -1) {
  1038. setParseVideo();
  1039. } else if (location.host.indexOf('jx.parwix.com:4433') !== -1) {
  1040. setParseVideo();
  1041. } else {
  1042. setParseVideo();
  1043. }
  1044. }
  1045.  
  1046. function displayNone(Tags) {
  1047. setTimeout(function () {
  1048. let style = document.createElement("style");
  1049. style.innerHTML = "\n";
  1050. for (let i = 0; i < Tags.length; i++) {
  1051. style.innerHTML += Tags[i] + "{display: none !important; height: 0 !important; width: 0 !important; visibility: hidden !important; max-height: 0 !important; max-width: 0 !important; opacity: 0 !important;}\n";
  1052. }
  1053. document.head.insertBefore(style, document.head.firstChild);
  1054. });
  1055. }
  1056. }
  1057.  
  1058. function showTip(msg, style = "") {
  1059. try {
  1060. // 该函数需要在top内运行,否则可能显示异常
  1061. if (window === top) {
  1062. let tip = document.querySelector(":root>tip");
  1063. if (tip && tip.nodeType === 1) {
  1064. // 防止中途新的showTip事件创建多个tip造成卡顿
  1065. tip.remove();
  1066. }
  1067. tip = document.createElement("tip");
  1068. // pointer-events: none; 禁用鼠标事件,input标签使用 disabled='disabled' 禁用input标签
  1069. tip.setAttribute("style", style + "pointer-events: none; opacity: 0; background-color: #222a; color: #fff; font-family: 微软雅黑,黑体,Droid Serif,Arial,sans-serif; font-size: 20px; text-align: center; padding: 6px; border-radius: 16px; position: fixed; transform: translate(-50%, -50%); left: 50%; bottom: 15%; z-index: 2147483647;");
  1070. tip.innerHTML = "<style>@keyframes showTip {0%{opacity: 0;} 33.34%{opacity: 1;} 66.67%{opacity: 1;} 100%{opacity: 0;}}</style>\n" + msg;
  1071. let time = msg.replace(new RegExp("\\s"), "").length / 2; // TODO 2个字/秒
  1072. // cubic-bezier(起始点, 起始点偏移量, 结束点偏移量, 结束点),这里的 cubic-bezier函数 表示动画速度的变化规律
  1073. tip.style.animation = "showTip " + (time > 2 ? time : 2) + "s cubic-bezier(0," + ((time - 1) > 0 ? (time - 1) / time : 0) + "," + (1 - ((time - 1) > 0 ? (time - 1) / time : 0)) + ",1) 1 normal";
  1074. document.root.appendChild(tip);
  1075. setTimeout(function () {
  1076. try {
  1077. tip.remove();
  1078. } catch (e) {
  1079. // 排除root没有找到tip
  1080. }
  1081. }, time * 1000);
  1082. } else {
  1083. top.postMessage(settings.key.encrypt("宝塔镇河妖\x00函数\x00showTip('" + msg + "')"), "*");
  1084. }
  1085. } catch (e) {
  1086. console.log(msg);
  1087. }
  1088. }
  1089. })();
  1090.  
  1091. async function require(url) {
  1092. const request = new XMLHttpRequest();
  1093. let result = null;
  1094. request.open("GET", url, false);
  1095. request.onload = function () {
  1096. result = eval(request.response);
  1097. console.log("use-scrypt.length = " + request.response.length);
  1098. };
  1099. try {
  1100. request.send();
  1101. } catch (e) {
  1102. let script = document.createElement("script");
  1103. script.src = url;
  1104. document.head.appendChild(script);
  1105. let nameKey = window.name;
  1106. // await 等待完成或window.name会莫名其妙被清空
  1107. await (function () {
  1108. return new Promise(function (resolve, reject) {
  1109. script.addEventListener("load", resolve);
  1110. script.addEventListener("error", reject);
  1111. });
  1112. })();
  1113. window.name = nameKey;
  1114. result = script;
  1115. }
  1116. return result;
  1117. }
  1118. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址