index3.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. /**
  2. pathLib: {
  3. join: [Function: join],
  4. dirname: [Function: dirname],
  5. readDir: [Function (anonymous)],
  6. readFile: [Function (anonymous)],
  7. stat: [Function (anonymous)]
  8. }
  9. path
  10. path_dir
  11. **/
  12. function naturalSort(arr, key) {
  13. return arr.sort((a, b) => a[key].localeCompare(b[key], undefined, {numeric: true, sensitivity: 'base'}));
  14. }
  15. async function main() {
  16. // let js_order = ['360影视[官]', '菜狗[官]', '奇珍异兽[官]', '优酷[官]', '腾云驾雾[官]', '百忙无果[官]', '哔哩影视[官]', '采集之王[合]', '采王道长[合]'];
  17. //将custom.json里的 https://wogg.link/ 已经失效 改为https://www.wogg.net/
  18. let js_order = ['🇵玩偶哥哥|网盘','🧑豆瓣[官]', '🎁采王道长[合]', '🎁直播转点播[合]'];
  19. let js_path = './drpy_js';
  20. let live_path = './lives';
  21. let config_path = './custom.json';
  22. let js_api = './drpy_libs/drpy2.min.js';
  23. let parse_apis = [
  24. '777,https://jx.777jiexi.com/player/?url=,0',
  25. '8090g,https://www.8090g.cn/jiexi/?url=,0',
  26. 'ik9,https://yparse.ik9.cc/index.php?url=,0',
  27. '杰森,https://jx.jsonplayer.com/player/?url=,0',
  28. '阳途,https://jx.yangtu.top/?url=,0',
  29. '冰豆,https://bd.jx.cn/?url=,0',
  30. 'm3u8TV,https://jx.m3u8.tv/jiexi/?url=,0',
  31. '听乐,https://jx.dj6u.com/?url=,0',
  32. '虾米,https://jx.xmflv.com/?url=,0',
  33. '虾米2,https://jx.xmflv.cc/?url=,0',
  34. '云析,https://jx.yparse.com/index.php?url=,0',
  35. '红狐,https://player.mrgaocloud.com/player/?url=,0',
  36. ];
  37. let parses = parse_apis.map((it) => {
  38. let _name = it.split(',')[0];
  39. let _url = it.split(',')[1];
  40. let _type = it.split(',').length > 2 ? it.split(',')[2] : '0';
  41. _type = Number(_type);
  42. return {
  43. name: _name,
  44. url: _url,
  45. type: _type,
  46. 'ext': {
  47. 'flag': [
  48. 'qiyi',
  49. 'imgo',
  50. '爱奇艺',
  51. '奇艺',
  52. 'qq',
  53. 'qq 预告及花絮',
  54. '腾讯',
  55. 'youku',
  56. '优酷',
  57. 'pptv',
  58. 'PPTV',
  59. 'letv',
  60. '乐视',
  61. 'leshi',
  62. 'mgtv',
  63. '芒果',
  64. 'sohu',
  65. 'xigua',
  66. 'fun',
  67. '风行',
  68. ],
  69. },
  70. 'header': {
  71. 'User-Agent': 'Mozilla/5.0',
  72. },
  73. };
  74. });
  75. let js_files = pathLib.readDir(pathLib.join(path_dir, js_path)).filter(file => file && file.endsWith('.js'));
  76. // console.log(js_files);
  77. let live_files = pathLib.readDir(pathLib.join(path_dir, live_path));
  78. // console.log(live_files);
  79. let config_sites = [];
  80. try {
  81. let config_file = pathLib.readFile(pathLib.join(path_dir, config_path));
  82. config_sites = JSON.parse(config_file).sites;
  83. } catch (e) {
  84. console.log(`get config_file error:${e.message}`);
  85. }
  86. let channels = [];
  87. channels.push(
  88. /*
  89. {
  90. 'name': '稳定github直播',
  91. 'urls': [
  92. 'proxy://do=live&type=txt&ext=https://ghproxy.net/https://raw.githubusercontent.com/ssili126/tv/main/itvlist.txt',
  93. ],
  94. }
  95. */
  96. {
  97. "name": "范明明V6",
  98. "type": 0,
  99. "url": "https://live.fanmingming.com/tv/m3u/ipv6.m3u",
  100. "playerType": 1,
  101. "ua": "okhttp/3.15",
  102. "epg": "http://epg.112114.xyz/?ch={name}&date={date}",
  103. "logo": "https://epg.112114.xyz/logo/{name}.png"
  104. },
  105. {
  106. "name": "十四里",
  107. "type": 0,
  108. "url": "https://raw.cachefly.998111.xyz/ssili126/tv/main/itvlist.txt",
  109. "playerType": 1,
  110. "ua": "okhttp/3.15",
  111. "epg": "http://epg.112114.xyz/?ch={name}&date={date}",
  112. "logo": "https://epg.112114.xyz/logo/{name}.png"
  113. }
  114. );
  115. live_files.forEach((it) => {
  116. let absp = pathLib.join(path_dir, `${live_path}/${it}`).replace(/\\/g, '/');
  117. if (absp.includes('/zyplayer/file/')) {
  118. absp = 'http://127.0.0.1:9978/api/v1/file/' + absp.split('/zyplayer/file/')[1];
  119. }
  120. let aname = it.split('.')[0];
  121. channels.push(
  122. /*
  123. {
  124. 'name': aname,
  125. 'urls': [
  126. 'proxy://do=live&type=txt&ext=' + absp,
  127. ],
  128. }
  129. */
  130. {
  131. "name": aname,
  132. "type": 0,
  133. "url": absp,
  134. "playerType": 1,
  135. "ua": "okhttp/3.15",
  136. "epg": "http://epg.112114.xyz/?ch={name}&date={date}",
  137. "logo": "https://epg.112114.xyz/logo/{name}.png"
  138. }
  139. );
  140. });
  141. channels = channels.concat([
  142. /*
  143. {
  144. 'name': '云星日记直播',
  145. 'urls': [
  146. 'proxy://do=live&type=txt&ext=http://itvbox.cc/云星日记/Ipv4.txt',
  147. ],
  148. },
  149. {
  150. 'name': '本地嗅探器直播',
  151. 'urls': [
  152. 'proxy://do=live&type=txt&ext=http://127.0.0.1:5708/ysp',
  153. ],
  154. },
  155. */
  156. {
  157. "name": "摸鱼",
  158. "type": 0,
  159. "url": "http://我不是.摸鱼儿.top/live.php",
  160. "playerType": 1,
  161. "ua": "okhttp/3.15",
  162. "epg": "http://epg.112114.xyz/?ch={name}&date={date}",
  163. "logo": "https://epg.112114.xyz/logo/{name}.png"
  164. }
  165. ]);
  166. let json_config = {
  167. 'wallpaper': 'https://tuapi.eees.cc/api.php?category=fengjing&type=302',
  168. 'homepage': 'https://github.com/hjdhnx/hipy-server',
  169. "homeLogo": "./img/logo500x200-1.png",
  170. "spider": "./jar/pg.jar?md5=7633f8ea346c082b7aa163be58aed023",
  171. 'sites': [],
  172. 'parses': parses,
  173. 'flags': [
  174. 'imgo',
  175. 'youku',
  176. 'qq',
  177. 'qq 预告及花絮',
  178. 'iqiyi',
  179. 'qiyi',
  180. 'fun',
  181. 'letv',
  182. 'leshi',
  183. 'sohu',
  184. 'tudou',
  185. 'xigua',
  186. 'cntv',
  187. '1905',
  188. 'pptv',
  189. 'mgtv',
  190. 'wasu',
  191. 'bilibili',
  192. 'renrenmi',
  193. ],
  194. 'lives':
  195. channels
  196. /*
  197. 'lives': [
  198. {
  199. 'group': 'redirect',
  200. 'channels': channels,
  201. },
  202. ],
  203. */
  204. };
  205. js_files.forEach((it, index) => {
  206. let rname = it.replace('.js', '');
  207. let extras = [''];
  208. if (rname.includes('我的哔哩传参')) {
  209. extras = ['?type=url&params=../json/小学教育.json'];
  210. } else if (rname.includes('采集之王')) {
  211. extras = [
  212. '?type=url&params=../json/采集静态.json$1@采王道长[合]',
  213. '?type=url&params=../json/采集[zy]静态.json$1@采王zy[密]',
  214. '?type=url&params=../json/采集[密]静态.json@采王成人[密]',
  215. ];
  216. } else if (rname.includes('直播转点播')) {
  217. extras = [
  218. '?type=url&params=../json/live2cms.json',
  219. ];
  220. }
  221. let excludes = [];
  222. if (!excludes.includes(rname)) {
  223. extras.forEach((extra, index) => {
  224. let ext_str = 'drpy_t3';
  225. let _name = extras.length > 1 ? `${rname}${index}` : `${rname}`;
  226. let ext_name = extra.includes('@') ? extra.split('@')[1] : _name;
  227. extra = extra.split('@')[0];
  228. if (extra) {
  229. try {
  230. ext_str = extra.split('/').slice(-1)[0].split('.')[0];
  231. } catch (e) {
  232. }
  233. }
  234. ext_name = ext_name || `${rname}(${ext_str})`;
  235. let data = {
  236. 'key': extras.length > 1 ? `hipy_js_${rname}${index}` : `hipy_js_${rname}`,
  237. 'name': `${ext_name}`,// (drpy_t3)
  238. 'type': 3,
  239. 'api': js_api,
  240. 'searchable': 1,
  241. 'quickSearch': 1,
  242. 'filterable': 1,
  243. 'order_num': index,
  244. 'ext': `${js_path}/${it}${extra}`,
  245. };
  246. json_config.sites.push(data);
  247. });
  248. }
  249. });
  250. json_config.sites = json_config.sites.map(site => {
  251. let newName = site.name;
  252. if (/\[短\]|短/.test(newName)) {
  253. newName = '📲' + newName;
  254. } else if (newName.includes('[优]')) {
  255. newName = '🏆' + newName;
  256. } else if (newName.includes('[听]')) {
  257. newName = '🎧' + newName;
  258. } else if (newName.includes('[官]')) {
  259. newName = '🧑' + newName;
  260. } else if (newName.includes('[书]')) {
  261. newName = '📚' + newName;
  262. } else if (newName.includes('[合]')) {
  263. newName = '🎁' + newName;
  264. } else if (newName.includes('[漫]')) {
  265. newName = '💮' + newName;
  266. } else if (newName.includes('[盘]')) {
  267. newName = '💾' + newName;
  268. } else if (newName.includes('[球]')) {
  269. newName = '⚽' + newName;
  270. } else if (newName.includes('[飞]')) {
  271. newName = '✈️' + newName;
  272. } else if (newName.includes('[磁]')) {
  273. newName = '🧲' + newName;
  274. } else if (newName.includes('[虫]')) {
  275. newName = '🐞' + newName;
  276. } else if (/\[自动\]|\(自动\)/.test(newName)) {
  277. newName = '🤖' + newName;
  278. } else if (newName.includes('[资]')) {
  279. newName = '♻️' + newName;
  280. } else if (newName.includes('[儿]')) {
  281. newName = '👶' + newName;
  282. } else if (newName.includes('[V2]')) {
  283. newName = '🔱' + newName;
  284. } else if (newName.includes('[搜]')) {
  285. newName = '🔎' + newName;
  286. } else if (newName.includes('[播]')) {
  287. newName = '▶️' + newName;
  288. } else if (newName.includes('[密]')) {
  289. newName = '🚫' + newName;
  290. } else if (newName.includes('[画]')) {
  291. newName = '🖼️' + newName;
  292. } else if (newName.includes('[慢]')) {
  293. newName = '🐢' + newName;
  294. } else if (site['key'].startsWith('hipy_js')) {
  295. newName = '📺' + newName;
  296. } else {
  297. newName = '' + newName;
  298. }
  299. site.name = newName;
  300. return site;
  301. });
  302. config_sites = config_sites.map(site => {
  303. let newName = site.name;
  304. newName = '🇵' + newName; // 没有则加上 '🇵'
  305. site.name = newName;
  306. return site;
  307. });
  308. pg_config = config_sites;
  309. json_config.sites = json_config.sites.concat(config_sites);
  310. // 从 json_config.sites 中删除名称带 '[密]' 的站点
  311. json_config.sites = json_config.sites.filter(site =>!site.name.includes('[密]'));
  312. function customSort(a, b) {
  313. let i = js_order.indexOf(a.name.split('(')[0]);
  314. let j = js_order.indexOf(b.name.split('(')[0]);
  315. // 先按照 js_order 排序
  316. if (i!== -1 && j!== -1) {
  317. return i - j;
  318. } else if (i!== -1) {
  319. return -1;
  320. } else if (j!== -1) {
  321. return 1;
  322. }
  323. //筛选
  324. const regex = /(\[|【)(官|优|听|书|短|漫|画|合|资|自动|V2|球|飞|磁|儿|搜|盘|虫|播|慢)(\]|】)|短|📺|(自动)/;
  325. const matchA = a.name.match(regex);
  326. const matchB = b.name.match(regex);
  327. //排序 可自行修改
  328. if (matchA && matchB) {
  329. const order = ['[官]', '[合]', '[优]', '[听]', '[书]', '[短]','短', '[漫]', '[画]', '[资]', '[自动]','自动', '[V2]', '[球]', '[飞]', '[磁]', '[儿]', '[搜]', '[盘]', '[虫]', '[播]', '[慢]','📺'];
  330. const indexA = order.indexOf(matchA[0]);
  331. const indexB = order.indexOf(matchB[0]);
  332. if (indexA!== indexB) {
  333. return indexA - indexB;
  334. }
  335. } else if (matchA) {
  336. return -1;
  337. } else if (matchB) {
  338. return 1;
  339. }
  340. // 如果都不是正则匹配的部分,按名称排序
  341. let compareResult = a.name.localeCompare(b.name);
  342. // 单独处理“密”的匹配
  343. const regexForMiA = /(\[|【)密(\]|】)/;
  344. const matchAMi = a.name.match(regexForMiA);
  345. const regexForMiB = /(\[|【)密(\]|】)/;
  346. const matchBMi = b.name.match(regexForMiB);
  347. if (matchAMi &&!matchBMi) {
  348. compareResult = 1;
  349. } else if (!matchAMi && matchBMi) {
  350. compareResult = -1;
  351. }
  352. return compareResult;
  353. }
  354. //json_config.sites.sort(customSort);
  355. json_config.sites = Array.from(new Set(json_config.sites.sort(customSort).concat(pg_config)));
  356. //return JSON.stringify(json_config, null, "\t");
  357. let jsonString = JSON.stringify(json_config);
  358. jsonString = jsonString
  359. .replace('{"', '{\n"')
  360. .replace(',"si', ',\n"si')
  361. .replace(',"l', ',\n"l')
  362. .replaceAll(',"u', ', "u')
  363. .replaceAll('3,"', '3, "')
  364. .replaceAll('1,"', '1, "')
  365. .replaceAll('0,"', '0, "')
  366. .replaceAll(',"n', ', "n')
  367. .replace(',"sp', ',\n"sp')
  368. .replaceAll('[{', '[\n{')
  369. .replaceAll('],', '],\n')
  370. .replaceAll('","h', '",\n"h')
  371. .replaceAll('},{"', '},\n{"')
  372. .replaceAll('}]}', '}]\n}')
  373. .replaceAll('],', '],\n');
  374. return jsonString;
  375. }