You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

892 lines
29 KiB

  1. import { Crypto, _ } from 'assets://js/lib/cat.js'
  2. let host = '';
  3. let header = {
  4. 'User-Agent': 'okhttp/3.12.11'
  5. };
  6. let siteKey = '';
  7. let siteType = '';
  8. let siteJx = '';
  9. const urlPattern1 = /api\.php\/.*?\/vod/;
  10. const urlPattern2 = /api\.php\/.+?\.vod/;
  11. const parsePattern = /\/.+\\?.+=/;
  12. const parsePattern1 = /.*(url|v|vid|php\?id)=/;
  13. const parsePattern2 = /https?:\/\/[^\/]*/;
  14. const htmlVideoKeyMatch = [
  15. /player=new/,
  16. /<div id="video"/,
  17. /<div id="[^"]*?player"/,
  18. /\/\/视频链接/,
  19. /HlsJsPlayer\(/,
  20. /<iframe[\s\S]*?src="[^"]+?"/,
  21. /<video[\s\S]*?src="[^"]+?"/,
  22. ];
  23. async function init(cfg) {
  24. siteKey = cfg.skey;
  25. siteType = cfg.stype;
  26. host = cfg.ext;
  27. if (cfg.ext.hasOwnProperty('host')) { // for custom jx
  28. host = cfg.ext.host;
  29. siteJx = cfg.ext;
  30. }
  31. };
  32. async function request(reqUrl, ua, timeout = 60000) {
  33. let res = await req(reqUrl, {
  34. method: 'get',
  35. headers: ua ? ua : {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36'},
  36. timeout: timeout,
  37. });
  38. return res.content;
  39. }
  40. async function home(filter) {
  41. try {
  42. let url = getCateUrl(host);
  43. let jsonArray = null;
  44. if (url) {
  45. const json = await request(url, getHeaders(url));
  46. const obj = JSON.parse(json);
  47. if (obj.hasOwnProperty("list") && Array.isArray(obj.list)) {
  48. jsonArray = obj.list;
  49. } else if (
  50. obj.hasOwnProperty("data") &&
  51. obj.data.hasOwnProperty("list") &&
  52. Array.isArray(obj.data.list)
  53. ) {
  54. jsonArray = obj.data.list;
  55. } else if (obj.hasOwnProperty("data") && Array.isArray(obj.data)) {
  56. jsonArray = obj.data;
  57. }
  58. } else {
  59. // 通过filter列表读分类
  60. const filterStr = getFilterTypes(url, null);
  61. const classes = filterStr.split("\n")[0].split("+");
  62. jsonArray = [];
  63. for (let i = 1; i < classes.length; i++) {
  64. const kv = classes[i].trim().split("=");
  65. if (kv.length < 2) continue;
  66. const newCls = {
  67. type_name: kv[0].trim(),
  68. type_id: kv[1].trim(),
  69. };
  70. jsonArray.push(newCls);
  71. }
  72. }
  73. const result = { class: [] };
  74. if (jsonArray != null) {
  75. for (let i = 0; i < jsonArray.length; i++) {
  76. const jObj = jsonArray[i];
  77. const typeName = jObj.type_name;
  78. if (isBan(typeName)) continue;
  79. const typeId = jObj.type_id;
  80. const newCls = {
  81. type_id: typeId,
  82. type_name: typeName,
  83. };
  84. const typeExtend = jObj.type_extend;
  85. if (filter) {
  86. const filterStr = getFilterTypes(url, typeExtend);
  87. const filters = filterStr.split("\n");
  88. const filterArr = [];
  89. for (let k = (url) ? 1 : 0; k < filters.length; k++) {
  90. const l = filters[k].trim();
  91. if (!l) continue;
  92. const oneLine = l.split("+");
  93. let type = oneLine[0].trim();
  94. let typeN = type;
  95. if (type.includes("筛选")) {
  96. type = type.replace(/筛选/g, "");
  97. if (type === "class") typeN = "类型";
  98. else if (type === "area") typeN = "地区";
  99. else if (type === "lang") typeN = "语言";
  100. else if (type === "year") typeN = "年份";
  101. }
  102. const jOne = {
  103. key: type,
  104. name: typeN,
  105. value: [],
  106. };
  107. for (let j = 1; j < oneLine.length; j++) {
  108. const kv = oneLine[j].trim();
  109. const sp = kv.indexOf("=");
  110. if (sp === -1) {
  111. if (isBan(kv)) continue;
  112. jOne.value.push({ n: kv, v: kv });
  113. } else {
  114. const n = kv.substring(0, sp);
  115. if (isBan(n)) continue;
  116. jOne.value.push({
  117. n: n.trim(),
  118. v: kv.substring(sp + 1).trim(),
  119. });
  120. }
  121. }
  122. filterArr.push(jOne);
  123. }
  124. if (!result.hasOwnProperty("filters")) {
  125. result.filters = {};
  126. }
  127. result.filters[typeId] = filterArr;
  128. }
  129. result.class.push(newCls);
  130. }
  131. }
  132. return JSON.stringify(result);
  133. } catch (e) {
  134. }
  135. return "";
  136. }
  137. async function homeVod() {
  138. try {
  139. const apiUrl = host;
  140. let url = getRecommendUrl(apiUrl);
  141. let isTV = false;
  142. if (!url) {
  143. url = getCateFilterUrlPrefix(apiUrl) + "movie&page=1&area=&type=&start=";
  144. isTV = true;
  145. }
  146. const json = await request(url, getHeaders(url));
  147. const obj = JSON.parse(json);
  148. const videos = [];
  149. if (isTV) {
  150. const jsonArray = obj.data;
  151. for (let i = 0; i < jsonArray.length; i++) {
  152. const vObj = jsonArray[i];
  153. const v = {
  154. vod_id: vObj.nextlink,
  155. vod_name: vObj.title,
  156. vod_pic: vObj.pic,
  157. vod_remarks: vObj.state,
  158. };
  159. videos.push(v);
  160. }
  161. } else {
  162. const arrays = [];
  163. findJsonArray(obj, "vlist", arrays);
  164. if (arrays.length === 0) {
  165. findJsonArray(obj, "vod_list", arrays);
  166. }
  167. const ids = [];
  168. for (const jsonArray of arrays) {
  169. for (let i = 0; i < jsonArray.length; i++) {
  170. const vObj = jsonArray[i];
  171. const vid = vObj.vod_id;
  172. if (ids.includes(vid)) continue;
  173. ids.push(vid);
  174. const v = {
  175. vod_id: vid,
  176. vod_name: vObj.vod_name,
  177. vod_pic: vObj.vod_pic,
  178. vod_remarks: vObj.vod_remarks,
  179. };
  180. videos.push(v);
  181. }
  182. }
  183. }
  184. const result = {
  185. list: videos,
  186. };
  187. return JSON.stringify(result);
  188. } catch (e) {
  189. }
  190. return "";
  191. }
  192. async function category(tid, pg, filter, extend) {
  193. try {
  194. const apiUrl = host;
  195. let url = getCateFilterUrlPrefix(apiUrl) + tid + getCateFilterUrlSuffix(apiUrl);
  196. url = url.replace(/#PN#/g, pg);
  197. url = url.replace(/筛选class/g, extend?.class ?? "");
  198. url = url.replace(/筛选area/g, extend?.area ?? "");
  199. url = url.replace(/筛选lang/g, extend?.lang ?? "");
  200. url = url.replace(/筛选year/g, extend?.year ?? "");
  201. url = url.replace(/排序/g, extend?.排序 ?? "");
  202. const json = await request(url, getHeaders(url));
  203. const obj = JSON.parse(json);
  204. let totalPg = Infinity;
  205. try {
  206. if (obj.totalpage !== undefined && typeof obj.totalpage === "number") {
  207. totalPg = obj.totalpage;
  208. } else if (
  209. obj.pagecount !== undefined &&
  210. typeof obj.pagecount === "number"
  211. ) {
  212. totalPg = obj.pagecount;
  213. } else if (
  214. obj.data !== undefined &&
  215. typeof obj.data === "object" &&
  216. obj.data.total !== undefined &&
  217. typeof obj.data.total === "number" &&
  218. obj.data.limit !== undefined &&
  219. typeof obj.data.limit === "number"
  220. ) {
  221. const limit = obj.data.limit;
  222. const total = obj.data.total;
  223. totalPg = total % limit === 0 ? total / limit : Math.floor(total / limit) + 1;
  224. }
  225. } catch (e) {
  226. }
  227. const jsonArray =
  228. obj.list !== undefined
  229. ? obj.list
  230. : obj.data !== undefined && obj.data.list !== undefined
  231. ? obj.data.list
  232. : obj.data;
  233. const videos = [];
  234. if (jsonArray !== undefined) {
  235. for (let i = 0; i < jsonArray.length; i++) {
  236. const vObj = jsonArray[i];
  237. const v = {
  238. vod_id: vObj.vod_id !== undefined ? vObj.vod_id : vObj.nextlink,
  239. vod_name: vObj.vod_name !== undefined ? vObj.vod_name : vObj.title,
  240. vod_pic: vObj.vod_pic !== undefined ? vObj.vod_pic : vObj.pic,
  241. vod_remarks: vObj.vod_remarks !== undefined ? vObj.vod_remarks : vObj.state,
  242. };
  243. videos.push(v);
  244. }
  245. }
  246. const result = {
  247. page: pg,
  248. pagecount: totalPg,
  249. limit: 90,
  250. total: Infinity,
  251. list: videos,
  252. };
  253. return JSON.stringify(result);
  254. } catch (e) {
  255. SpiderDebug.log(e);
  256. }
  257. return "";
  258. }
  259. async function detail(ids) {
  260. try {
  261. const apiUrl = host;
  262. const url = getPlayUrlPrefix(apiUrl) + ids;
  263. const json = await request(url, getHeaders(url));
  264. const obj = JSON.parse(json);
  265. const result = {
  266. list: [],
  267. };
  268. const vod = {};
  269. genPlayList(apiUrl, obj, json, vod, ids);
  270. result.list.push(vod);
  271. return JSON.stringify(result);
  272. } catch (e) {
  273. }
  274. return "";
  275. }
  276. const parseUrlMap = new Map();
  277. function genPlayList(URL, object, json, vod, vid) {
  278. const playUrls = [];
  279. const playFlags = [];
  280. if (URL.includes("lfytyl.com")) {
  281. const data = object.data;
  282. vod.vod_id = data.vod_id || vid;
  283. vod.vod_name = data.vod_name;
  284. vod.vod_pic = data.vod_pic;
  285. vod.type_name = data.vod_class || "";
  286. vod.vod_year = data.vod_year || "";
  287. vod.vod_area = data.vod_area || "";
  288. vod.vod_remarks = data.vod_remarks || "";
  289. vod.vod_actor = data.vod_actor || "";
  290. vod.vod_director = data.vod_director || "";
  291. vod.vod_content = data.vod_content || "";
  292. vod.vod_play_from = data.vod_play_from;
  293. vod.vod_play_url = data.vod_play_url;
  294. return;
  295. }
  296. if (URL.includes("api.php/app")) {
  297. const data = object.data;
  298. vod.vod_id = data.vod_id || vid;
  299. vod.vod_name = data.vod_name;
  300. vod.vod_pic = data.vod_pic;
  301. vod.type_name = data.vod_class || "";
  302. vod.vod_year = data.vod_year || "";
  303. vod.vod_area = data.vod_area || "";
  304. vod.vod_remarks = data.vod_remarks || "";
  305. vod.vod_actor = data.vod_actor || "";
  306. vod.vod_director = data.vod_director || "";
  307. vod.vod_content = data.vod_content || "";
  308. const vodUrlWithPlayer = data.vod_url_with_player;
  309. for (let i = 0; i < vodUrlWithPlayer.length; i++) {
  310. const from = vodUrlWithPlayer[i];
  311. let flag = from.code.trim();
  312. if (flag === "") flag = from.name.trim();
  313. playFlags.push(flag);
  314. playUrls.push(from.url);
  315. let purl = from.parse_api;
  316. const parseUrls = parseUrlMap.get(flag) || [];
  317. if (purl && !parseUrls.includes(purl)) {
  318. parseUrls.push(purl);
  319. }
  320. parseUrlMap.set(flag, parseUrls);
  321. }
  322. } else if (URL.includes("xgapp")) {
  323. const data = object.data.vod_info;
  324. vod.vod_id = data.vod_id || vid;
  325. vod.vod_name = data.vod_name;
  326. vod.vod_pic = data.vod_pic;
  327. vod.type_name = data.vod_class || "";
  328. vod.vod_year = data.vod_year || "";
  329. vod.vod_area = data.vod_area || "";
  330. vod.vod_remarks = data.vod_remarks || "";
  331. vod.vod_actor = data.vod_actor || "";
  332. vod.vod_director = data.vod_director || "";
  333. vod.vod_content = data.vod_content || "";
  334. const vodUrlWithPlayer = data.vod_url_with_player;
  335. for (let i = 0; i < vodUrlWithPlayer.length; i++) {
  336. const from = vodUrlWithPlayer[i];
  337. let flag = from.code.trim();
  338. if (flag === "") flag = from.name.trim();
  339. playFlags.push(flag);
  340. playUrls.push(from.url);
  341. const purl = from.parse_api.trim();
  342. const parseUrls = parseUrlMap.get(flag) || [];
  343. if (purl && !parseUrls.includes(purl)) {
  344. parseUrls.push(purl);
  345. }
  346. parseUrlMap.set(flag, parseUrls);
  347. }
  348. } else if (URL.includes(".vod")) {
  349. const data = object.data;
  350. vod.vod_id = data.vod_id || vid;
  351. vod.vod_name = data.vod_name;
  352. vod.vod_pic = data.vod_pic;
  353. vod.type_name = data.vod_class || "";
  354. vod.vod_year = data.vod_year || "";
  355. vod.vod_area = data.vod_area || "";
  356. vod.vod_remarks = data.vod_remarks || "";
  357. vod.vod_actor = data.vod_actor || "";
  358. vod.vod_director = data.vod_director || "";
  359. vod.vod_content = data.vod_content || "";
  360. const vodUrlWithPlayer = data.vod_play_list;
  361. for (let i = 0; i < vodUrlWithPlayer.length; i++) {
  362. const from = vodUrlWithPlayer[i];
  363. let flag = from.player_info.from.trim();
  364. if (flag === "") flag = from.player_info.show.trim();
  365. playFlags.push(flag);
  366. playUrls.push(from.url);
  367. try {
  368. const parses = [];
  369. const parse1 = from.player_info.parse.split(",");
  370. const parse2 = from.player_info.parse2.split(",");
  371. parses.push(...parse1, ...parse2);
  372. const parseUrls = parseUrlMap.get(flag) || [];
  373. for (const purl of parses) {
  374. if (purl.includes("http")) {
  375. const match = purl.match(parsePattern1);
  376. if (match) {
  377. parseUrls.push(match[0]);
  378. }
  379. } else if (purl.includes("//")) {
  380. const match = purl.match(parsePattern1);
  381. if (match) {
  382. parseUrls.push("http:" + match[0]);
  383. }
  384. } else {
  385. const urlMatch = URL.match(parsePattern2);
  386. if (urlMatch) {
  387. const match = URL.match(parsePattern1);
  388. if (match) {
  389. parseUrls.push(urlMatch[0] + match[0]);
  390. }
  391. }
  392. }
  393. if (purl.includes("..")) purl = purl.replace(/\.\./g, ".").trim();
  394. if (purl && !parseUrls.includes(purl)) {
  395. parseUrls.push(purl);
  396. }
  397. }
  398. parseUrlMap.set(flag, parseUrls);
  399. } catch (e) {
  400. }
  401. }
  402. } else if (URLPattern1.matcher(URL).find()) {
  403. // Same implementation as the previous cases
  404. }
  405. vod.vod_play_from = playFlags.join("$$$");
  406. vod.vod_play_url = playUrls.join("$$$");
  407. }
  408. async function play(flag, id, vipFlags) {
  409. try {
  410. // let parseUrls = parseUrlMap.get(flag);
  411. let parseUrls = siteJx[flag]; // custom sitejx
  412. if (!parseUrls) {
  413. if (siteJx.hasOwnProperty('*')) { // all jx
  414. parseUrls = siteJx['*'];
  415. } else {
  416. parseUrls = [];
  417. }
  418. }
  419. if (parseUrls.length > 0) {
  420. const result = await getFinalVideo(flag, parseUrls, id);
  421. if (result !== null) {
  422. return JSON.stringify(result);
  423. }
  424. }
  425. if (isVideo(id)) {
  426. const result = {
  427. parse: 0,
  428. playUrl: "",
  429. url: id
  430. };
  431. return JSON.stringify(result);
  432. } else {
  433. const result = {
  434. parse: 1,
  435. jx: "1",
  436. url: id
  437. };
  438. return JSON.stringify(result);
  439. }
  440. } catch (e) {
  441. // Handle any error here
  442. }
  443. return "";
  444. }
  445. async function search(key, quick) {
  446. try {
  447. const apiUrl = host;
  448. const url = getSearchUrl(apiUrl, encodeURIComponent(key));
  449. const json = await request(url, getHeaders(url));
  450. const obj = JSON.parse(json);
  451. let jsonArray = null;
  452. const videos = [];
  453. if (obj.list instanceof Array) {
  454. jsonArray = obj.list;
  455. } else if (obj.data instanceof Object && obj.data.list instanceof Array) {
  456. jsonArray = obj.data.list;
  457. } else if (obj.data instanceof Array) {
  458. jsonArray = obj.data;
  459. }
  460. if (jsonArray !== null) {
  461. for (const vObj of jsonArray) {
  462. if (vObj.vod_id) {
  463. const v = {
  464. vod_id: vObj.vod_id,
  465. vod_name: vObj.vod_name,
  466. vod_pic: vObj.vod_pic,
  467. vod_remarks: vObj.vod_remarks
  468. };
  469. videos.push(v);
  470. } else {
  471. const v = {
  472. vod_id: vObj.nextlink,
  473. vod_name: vObj.title,
  474. vod_pic: vObj.pic,
  475. vod_remarks: vObj.state
  476. };
  477. videos.push(v);
  478. }
  479. }
  480. }
  481. const result = { list: videos };
  482. return JSON.stringify(result);
  483. } catch (error) {
  484. }
  485. return "";
  486. }
  487. async function getFinalVideo(flag, parseUrls, url) {
  488. let htmlPlayUrl = "";
  489. for (const parseUrl of parseUrls) {
  490. if (parseUrl === "" || parseUrl === "null") {
  491. continue;
  492. }
  493. const playUrl = parseUrl + url;
  494. const content = await request(playUrl, null, 10000); // 10秒请求,能更好过滤webjx
  495. let tryJson = null;
  496. try {
  497. tryJson = jsonParse(url, content);
  498. } catch (error) { }
  499. if (tryJson !== null && tryJson.hasOwnProperty("url") && tryJson.hasOwnProperty("header")) {
  500. tryJson.header = JSON.stringify(tryJson.header);
  501. return tryJson;
  502. }
  503. if (content.includes("<html")) {
  504. let sniffer = false;
  505. for (const p of htmlVideoKeyMatch) {
  506. if (p.test(content)) {
  507. sniffer = true;
  508. break;
  509. }
  510. }
  511. if (sniffer) {
  512. htmlPlayUrl = parseUrl;
  513. }
  514. }
  515. }
  516. if (htmlPlayUrl !== "") { // 不支持sniffer
  517. const result = {
  518. parse: 0,
  519. playUrl: "",
  520. url: url
  521. };
  522. return JSON.stringify(result);
  523. }
  524. return null;
  525. }
  526. function jsonParse(input, json) {
  527. try {
  528. // 处理解析接口返回的报文,如果返回的报文中包含header信息,就加到返回值中
  529. let jsonPlayData = JSON.parse(json);
  530. // 处理293的解析结果url在data字段的解析
  531. if (jsonPlayData.hasOwnProperty("data") && typeof jsonPlayData.data === "object" && !jsonPlayData.hasOwnProperty("url")) {
  532. jsonPlayData = jsonPlayData.data;
  533. }
  534. let url = jsonPlayData.url;
  535. if (url.startsWith("//")) {
  536. url = "https:" + url;
  537. }
  538. if (!url.trim().startsWith("http")) {
  539. return null;
  540. }
  541. if (url === input) {
  542. if (isVip(url) || !isVideoFormat(url)) {
  543. return null;
  544. }
  545. }
  546. if (isBlackVodUrl(input, url)) {
  547. return null;
  548. }
  549. let headers = {};
  550. if (jsonPlayData.hasOwnProperty("header")) {
  551. headers = jsonPlayData.header;
  552. } else if (jsonPlayData.hasOwnProperty("Header")) {
  553. headers = jsonPlayData.Header;
  554. } else if (jsonPlayData.hasOwnProperty("headers")) {
  555. headers = jsonPlayData.headers;
  556. } else if (jsonPlayData.hasOwnProperty("Headers")) {
  557. headers = jsonPlayData.Headers;
  558. }
  559. let ua = "";
  560. if (jsonPlayData.hasOwnProperty("user-agent")) {
  561. ua = jsonPlayData["user-agent"];
  562. } else if (jsonPlayData.hasOwnProperty("User-Agent")) {
  563. ua = jsonPlayData["User-Agent"];
  564. }
  565. if (ua.trim().length > 0) {
  566. headers["User-Agent"] = " " + ua;
  567. }
  568. let referer = "";
  569. if (jsonPlayData.hasOwnProperty("referer")) {
  570. referer = jsonPlayData.referer;
  571. } else if (jsonPlayData.hasOwnProperty("Referer")) {
  572. referer = jsonPlayData.Referer;
  573. }
  574. if (referer.trim().length > 0) {
  575. headers["Referer"] = " " + referer;
  576. }
  577. headers = fixJsonVodHeader(headers, input, url);
  578. const taskResult = {
  579. header: headers,
  580. url: url,
  581. parse: "0"
  582. };
  583. return taskResult;
  584. } catch (error) {
  585. }
  586. return null;
  587. }
  588. function isVip(url) {
  589. try {
  590. let isVip = false;
  591. const host = new URL(url).hostname;
  592. const vipWebsites = ["iqiyi.com", "v.qq.com", "youku.com", "le.com", "tudou.com", "mgtv.com", "sohu.com", "acfun.cn", "bilibili.com", "baofeng.com", "pptv.com"];
  593. for (let b = 0; b < vipWebsites.length; b++) {
  594. if (host.includes(vipWebsites[b])) {
  595. if (vipWebsites[b] === "iqiyi.com") {
  596. // 爱奇艺需要特殊处理
  597. if (url.includes("iqiyi.com/a_") || url.includes("iqiyi.com/w_") || url.includes("iqiyi.com/v_")) {
  598. isVip = true;
  599. break;
  600. }
  601. } else {
  602. isVip = true;
  603. break;
  604. }
  605. }
  606. }
  607. return isVip;
  608. } catch (e) {
  609. }
  610. return false;
  611. }
  612. function isBlackVodUrl(input, url) {
  613. return url.includes("973973.xyz") || url.includes(".fit:");
  614. }
  615. function fixJsonVodHeader(headers, input, url) {
  616. if (headers === null) {
  617. headers = {};
  618. }
  619. if (input.includes("www.mgtv.com")) {
  620. headers["Referer"] = " ";
  621. headers["User-Agent"] = " Mozilla/5.0";
  622. } else if (url.includes("titan.mgtv")) {
  623. headers["Referer"] = " ";
  624. headers["User-Agent"] = " Mozilla/5.0";
  625. } else if (input.includes("bilibili")) {
  626. headers["Referer"] = " https://www.bilibili.com/";
  627. headers["User-Agent"] = " " + Misc.UaWinChrome;
  628. }
  629. return headers;
  630. }
  631. const snifferMatch = /http((?!http).){26,}?\.(m3u8|mp4|flv|avi|mkv|rm|wmv|mpg)\?.*|http((?!http).){26,}\.(m3u8|mp4|flv|avi|mkv|rm|wmv|mpg)|http((?!http).){26,}\/m3u8\?pt=m3u8.*|http((?!http).)*?default\.ixigua\.com\/.*|http((?!http).)*?cdn-tos[^\?]*|http((?!http).)*?\/obj\/tos[^\?]*|http.*?\/player\/m3u8play\.php\?url=.*|http.*?\/player\/.*?[pP]lay\.php\?url=.*|http.*?\/playlist\/m3u8\/\?vid=.*|http.*?\.php\?type=m3u8&.*|http.*?\/download.aspx\?.*|http.*?\/api\/up_api.php\?.*|https.*?\.66yk\.cn.*|http((?!http).)*?netease\.com\/file\/.*/;
  632. function isVideoFormat(url) {
  633. if (snifferMatch.test(url)) {
  634. return !url.includes("cdn-tos") || !url.includes(".js");
  635. }
  636. return false;
  637. }
  638. function isVideo(url) {
  639. if (!url.includes(".mp4") || !url.includes(".m3u8")) {
  640. return true;
  641. }
  642. return false;
  643. }
  644. function UA(url) {
  645. if (url.includes(".vod")) {
  646. return "okhttp/4.1.0";
  647. }
  648. }
  649. function getCateUrl(URL) {
  650. if (URL.includes("api.php/app") || URL.includes("xgapp")) {
  651. return URL + "nav?token=";
  652. } else if (URL.includes(".vod")) {
  653. return URL + "/types";
  654. } else {
  655. return "";
  656. }
  657. }
  658. function getPlayUrlPrefix(URL) {
  659. if (URL.includes("api.php/app") || URL.includes("xgapp")) {
  660. return URL + "video_detail?id=";
  661. } else if (URL.includes(".vod")) {
  662. return URL + "/detail?vod_id=";
  663. } else {
  664. return "";
  665. }
  666. }
  667. function getRecommendUrl(URL) {
  668. if (URL.includes("api.php/app") || URL.includes("xgapp")) {
  669. return URL + "index_video?token=";
  670. } else if (URL.includes(".vod")) {
  671. return URL + "/vodPhbAll";
  672. } else {
  673. return "";
  674. }
  675. }
  676. function getFilterTypes(URL, typeExtend) {
  677. let str = "";
  678. if (typeExtend !== null) {
  679. for (let key in typeExtend) {
  680. if (key === "class" || key === "area" || key === "lang" || key === "year") {
  681. try {
  682. str += "筛选" + key + "+全部=+" + typeExtend[key].replace(/,/g, "+") + "\n";
  683. } catch (e) { }
  684. }
  685. }
  686. }
  687. if (URL.includes(".vod")) {
  688. str += "\n" + "排序+全部=+最新=time+最热=hits+评分=score";
  689. } else if (URL.includes("api.php/app") || URL.includes("xgapp")) {
  690. // Do nothing, leave the string as it is.
  691. } else {
  692. str = "分类+全部=+电影=movie+连续剧=tvplay+综艺=tvshow+动漫=comic+4K=movie_4k+体育=tiyu\n筛选class+全部=+喜剧+爱情+恐怖+动作+科幻+剧情+战争+警匪+犯罪+动画+奇幻+武侠+冒险+枪战+恐怖+悬疑+惊悚+经典+青春+文艺+微电影+古装+历史+运动+农村+惊悚+惊悚+伦理+情色+福利+三级+儿童+网络电影\n筛选area+全部=+大陆+香港+台湾+美国+英国+法国+日本+韩国+德国+泰国+印度+西班牙+加拿大+其他\n筛选year+全部=+2023+2022+2021+2020+2019+2018+2017+2016+2015+2014+2013+2012+2011+2010+2009+2008+2007+2006+2005+2004+2003+2002+2001+2000";
  693. }
  694. return str;
  695. }
  696. function getCateFilterUrlSuffix(URL) {
  697. if (URL.includes("api.php/app") || URL.includes("xgapp")) {
  698. return "&class=筛选class&area=筛选area&lang=筛选lang&year=筛选year&limit=18&pg=#PN#";
  699. } else if (URL.includes(".vod")) {
  700. return "&class=筛选class&area=筛选area&lang=筛选lang&year=筛选year&by=排序&limit=18&page=#PN#";
  701. } else {
  702. return "&page=#PN#&area=筛选area&type=筛选class&start=筛选year";
  703. }
  704. }
  705. function getCateFilterUrlPrefix(URL) {
  706. if (URL.includes("api.php/app") || URL.includes("xgapp")) {
  707. return URL + "video?tid=";
  708. } else if (URL.includes(".vod")) {
  709. return URL + "?type=";
  710. } else {
  711. return URL + "?ac=list&class=";
  712. }
  713. }
  714. function isBan(key) {
  715. return key === "伦理" || key === "情色" || key === "福利";
  716. }
  717. function getSearchUrl(URL, KEY) {
  718. if (URL.includes(".vod")) {
  719. return URL + "?wd=" + KEY + "&page=";
  720. } else if (URL.includes("api.php/app") || URL.includes("xgapp")) {
  721. return URL + "search?text=" + KEY + "&pg=";
  722. } else if (urlPattern1.test(URL)) {
  723. return URL + "?ac=list&zm=" + KEY + "&page=";
  724. }
  725. return "";
  726. }
  727. function findJsonArray(obj, match, result) {
  728. Object.keys(obj).forEach((k) => {
  729. try {
  730. const o = obj[k];
  731. if (k === match && Array.isArray(o)) {
  732. result.push(o);
  733. }
  734. if (typeof o === "object" && o !== null) {
  735. if (Array.isArray(o)) {
  736. o.forEach((item) => {
  737. if (typeof item === "object" && item !== null) {
  738. findJsonArray(item, match, result);
  739. }
  740. });
  741. } else {
  742. findJsonArray(o, match, result);
  743. }
  744. }
  745. } catch (e) {
  746. }
  747. });
  748. }
  749. function jsonArr2Str(array) {
  750. const strings = [];
  751. for (let i = 0; i < array.length; i++) {
  752. try {
  753. strings.push(array[i]);
  754. } catch (e) {
  755. }
  756. }
  757. return strings.join(",");
  758. }
  759. function getHeaders(URL) {
  760. const headers = {};
  761. headers["User-Agent"] = UA(URL);
  762. return headers;
  763. }
  764. function isJsonString(str) {
  765. try {
  766. JSON.parse(str);
  767. } catch (e) {
  768. return false;
  769. }
  770. return true;
  771. }
  772. export function __jsEvalReturn() {
  773. return {
  774. init: init,
  775. home: home,
  776. homeVod: homeVod,
  777. category: category,
  778. detail: detail,
  779. play: play,
  780. search: search,
  781. };
  782. }