libhd_open.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. import { Crypto, load, _ } from 'assets://js/lib/cat.js';
  2. // siteUrl = 'http://proxy.liushiquan.eu.org/https://www.libhd.com';
  3. let siteUrl = 'https://www.libhd.com';
  4. let siteKey = '';
  5. let siteType = 0;
  6. let headers = {
  7. 'User-Agent': 'Mozilla/5.0 (Linux; Android 12; Redmi K30 Build/SKQ1.210908.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/96.0.4664.104 Mobile Safari/537.36',
  8. 'Sec-Fetch-Site': 'cross--site',
  9. 'Sec-Fetch-Mode': 'navigate',
  10. 'Sec-Fetch-Dest': 'iframe',
  11. };
  12. async function request(reqUrl, postData, get) {
  13. let res = await req(reqUrl, {
  14. method: get ? 'get' : 'post',
  15. headers: headers,
  16. data: postData || {},
  17. postType: get ? '' : 'form',
  18. timeout: 15000,
  19. });
  20. let content = res.content;
  21. return content;
  22. }
  23. async function init(cfg) {
  24. siteKey = cfg.skey;
  25. siteType = cfg.stype;
  26. if(cfg['ext']) {
  27. siteUrl = cfg['ext'];
  28. }
  29. }
  30. async function home(filter) {
  31. let classes = [{
  32. type_id: '1',
  33. type_name: '电影',
  34. },{
  35. type_id: '2',
  36. type_name: '剧集',
  37. },{
  38. type_id: '3',
  39. type_name: '综艺',
  40. },{
  41. type_id: '4',
  42. type_name: '动漫',
  43. }];
  44. let filterObj = genFilterObj();
  45. return JSON.stringify({
  46. class: classes,
  47. filters: filterObj
  48. });
  49. }
  50. async function homeVod() {
  51. let videos = await getVideos(siteUrl);
  52. return JSON.stringify({
  53. list: videos,
  54. });
  55. }
  56. async function category(tid, pg, filter, extend) {
  57. if (!pg) pg = 1;
  58. if (pg <= 0) pg = 1;
  59. let url = siteUrl + '/vodshow/' + tid + '-';
  60. if(extend['area'] && extend['area'].length > 0) {
  61. url += extend['area'];
  62. }
  63. url += '--';
  64. if(extend['type'] && extend['type'].length > 0) {
  65. url += extend['type'];
  66. }
  67. url += '-----';
  68. if (pg > 1) {
  69. url += pg;
  70. }
  71. url += '---';
  72. if(extend['year'] && extend['year'].length > 0) {
  73. url += extend['year'];
  74. }
  75. url += '.html';
  76. let videos = await getVideos(url);
  77. return JSON.stringify({
  78. list: videos,
  79. page: pg,
  80. });
  81. }
  82. async function detail(id) {
  83. try {
  84. const html = await request(siteUrl + id);
  85. const $ = load(html);
  86. let content = $('div#height_limit').text();
  87. let playFroms = [];
  88. let playUrls = [];
  89. let tabs = $('a.swiper-slide');
  90. let cards = $('ul.anthology-list-play');
  91. for(let i=0;i<tabs.length;i++) {
  92. let tname = $(tabs[i]).text();
  93. playFroms.push(tname.trim());
  94. let nameUrls = _.map($(cards[i]).find('li > a'), (n) => {
  95. return $(n).text() + '$' + $(n).attr('href');
  96. });
  97. playUrls.push(nameUrls.join('#'));
  98. }
  99. const video = {
  100. vod_play_from: playFroms.join('$$$'),
  101. vod_play_url: playUrls.join('$$$'),
  102. vod_content: content,
  103. };
  104. const list = [video];
  105. const result = { list };
  106. return JSON.stringify(result);
  107. } catch (e) {
  108. //console.log('err', e);
  109. }
  110. return null;
  111. }
  112. async function search(wd, quick, pg) {
  113. let url = siteUrl + '/vodsearch/-------------.html?wd=' + wd;
  114. let videos = await getVideos(url);
  115. return JSON.stringify({
  116. list: videos,
  117. });
  118. }
  119. async function play(flag, id, flags) {
  120. let playUrl = siteUrl + id;
  121. const html = await request(playUrl);
  122. const $ = load(html);
  123. for(const n of $('script')) {
  124. if($(n).text().indexOf('player_aaaa=') > 0) {
  125. let url = JSON.parse($(n).text().split('player_aaaa=')[1])['url'];
  126. if(url) {
  127. playUrl = url;
  128. }
  129. if (url.indexOf('libhd') == 0) {
  130. playUrl = await getTx(url);
  131. }
  132. if (url.indexOf('alip.speechless.pw') > 0) {
  133. playUrl = await getFx(url);
  134. }
  135. return JSON.stringify({
  136. parse: 0,
  137. url: playUrl,
  138. });
  139. }
  140. }
  141. return JSON.stringify({
  142. parse: 1,
  143. url: playUrl,
  144. });
  145. }
  146. function genFilterObj() {
  147. return {
  148. '1': [{
  149. key: 'type',
  150. name: '类型',
  151. value: [{n:'全部',v:''},{n:'喜剧',v:'喜剧'},{n:'爱情',v:'爱情'},{n:'恐怖',v:'恐怖'},{n:'动作',v:'动作'},{n:'科幻',v:'科幻'},{n:'剧情',v:'剧情'},{n:'战争',v:'战争'},{n:'警匪',v:'警匪'},{n:'犯罪',v:'犯罪'},{n:'动画',v:'动画'},{n:'奇幻',v:'奇幻'},{n:'武侠',v:'武侠'},{n:'冒险',v:'冒险'},{n:'枪战',v:'枪战'}]
  152. },{
  153. key: 'area',
  154. name: '地区',
  155. value: [{n:'全部',v:''},{n:'大陆',v:'大陆'},{n:'香港',v:'香港'},{n:'台湾',v:'台湾'},{n:'美国',v:'美国'},{n:'法国',v:'法国'},{n:'英国',v:'英国'},{n:'日本',v:'日本'},{n:'韩国',v:'韩国'},{n:'德国',v:'德国'},{n:'泰国',v:'泰国'},{n:'印度',v:'印度'},{n:'意大利',v:'意大利'},{n:'西班牙',v:'西班牙'},{n:'加拿大',v:'加拿大'},{n:'其他',v:'其他'}]
  156. },{
  157. key: 'year',
  158. name: '年份',
  159. value: [{n:'全部',v:''},{n:'2024',v:'2024'},{n:'2023',v:'2023'},{n:'2022',v:'2022'},{n:'2021',v:'2021'},{n:'2020',v:'2020'},{n:'2019',v:'2019'},{n:'2018',v:'2018'},{n:'2017',v:'2017'},{n:'2016',v:'2016'},{n:'2015',v:'2015'},{n:'2014',v:'2014'},{n:'2013',v:'2013'},{n:'2012',v:'2012'},{n:'2011',v:'2011'},{n:'2010',v:'2010'}]
  160. }],
  161. '2':[{
  162. key: 'type',
  163. name: '类型',
  164. value: [{n:'全部',v:''},{n:'古装',v:'古装'},{n:'战争',v:'战争'},{n:'青春偶像',v:'青春偶像'},{n:'喜剧',v:'喜剧'},{n:'家庭',v:'家庭'},{n:'犯罪',v:'犯罪'},{n:'动作',v:'动作'},{n:'奇幻',v:'奇幻'},{n:'剧情',v:'剧情'},{n:'历史',v:'历史'},{n:'经典',v:'经典'},{n:'乡村',v:'乡村'},{n:'情景',v:'情景'},{n:'商战',v:'商战'},{n:'网剧',v:'网剧'}]
  165. },{
  166. key: 'area',
  167. name: '地区',
  168. value: [{n:'全部',v:''},{n:'内地',v:'内地'},{n:'韩国',v:'韩国'},{n:'香港',v:'香港'},{n:'台湾',v:'台湾'},{n:'日本',v:'日本'},{n:'美国',v:'美国'},{n:'泰国',v:'泰国'},{n:'英国',v:'英国'},{n:'新加坡',v:'新加坡'},{n:'其他',v:'其他'}]
  169. },{
  170. key: 'year',
  171. name: '年份',
  172. value: [{n:'全部',v:''},{n:'2024',v:'2024'},{n:'2023',v:'2023'},{n:'2022',v:'2022'},{n:'2021',v:'2021'},{n:'2020',v:'2020'},{n:'2019',v:'2019'},{n:'2018',v:'2018'},{n:'2017',v:'2017'},{n:'2016',v:'2016'},{n:'2015',v:'2015'},{n:'2014',v:'2014'},{n:'2013',v:'2013'},{n:'2012',v:'2012'},{n:'2011',v:'2011'},{n:'2010',v:'2010'}]
  173. }],
  174. '3':[{
  175. key: 'type',
  176. name: '类型',
  177. value: [{n:'全部',v:''},{n:'选秀',v:'选秀'},{n:'情感',v:'情感'},{n:'访谈',v:'访谈'},{n:'播报',v:'播报'},{n:'旅游',v:'旅游'},{n:'音乐',v:'音乐'},{n:'美食',v:'没事'},{n:'纪实',v:'纪实'},{n:'曲艺',v:'曲艺'},{n:'生活',v:'生活'},{n:'游戏互动',v:'游戏互动'},{n:'财经',v:'财经'},{n:'求职',v:'求职'}]
  178. },{
  179. key: 'area',
  180. name: '地区',
  181. value: [{n:'全部',v:''},{n:'内地',v:'内地'},{n:'港台',v:'港台'},{n:'日韩',v:'日韩'},{n:'欧美',v:'欧美'}]
  182. },{
  183. key: 'year',
  184. name: '年份',
  185. value: [{n:'全部',v:''},{n:'2024',v:'2024'},{n:'2023',v:'2023'},{n:'2022',v:'2022'},{n:'2021',v:'2021'},{n:'2020',v:'2020'},{n:'2019',v:'2019'},{n:'2018',v:'2018'},{n:'2017',v:'2017'},{n:'2016',v:'2016'},{n:'2015',v:'2015'},{n:'2014',v:'2014'},{n:'2013',v:'2013'},{n:'2012',v:'2012'},{n:'2011',v:'2011'},{n:'2010',v:'2010'}]
  186. }],
  187. '4':[{
  188. key: 'type',
  189. name: '类型',
  190. value: [{n:'全部',v:''},{n:'情感',v:'情感'},{n:'科幻',v:'科幻'},{n:'热血',v:'热血'},{n:'推理',v:'推理'},{n:'搞笑',v:'搞笑'},{n:'冒险',v:'冒险'},{n:'萝莉',v:'萝莉'},{n:'校园',v:'校园'},{n:'动作',v:'动作'},{n:'机战',v:'机战'},{n:'运动',v:'运动'},{n:'战争',v:'战争'},{n:'少年',v:'少年'},{n:'少女',v:'少女'},{n:'社会',v:'社会'}]
  191. },{
  192. key: 'area',
  193. name: '地区',
  194. value: [{n:'全部',v:''},{n:'国产',v:'国产'},{n:'日本',v:'日本'},{n:'欧美',v:'欧美'},{n:'其他',v:'其他'}]
  195. },{
  196. key: 'year',
  197. name: '年份',
  198. value: [{n:'全部',v:''},{n:'2024',v:'2024'},{n:'2023',v:'2023'},{n:'2022',v:'2022'},{n:'2021',v:'2021'},{n:'2020',v:'2020'},{n:'2019',v:'2019'},{n:'2018',v:'2018'},{n:'2017',v:'2017'},{n:'2016',v:'2016'},{n:'2015',v:'2015'},{n:'2014',v:'2014'},{n:'2013',v:'2013'},{n:'2012',v:'2012'},{n:'2011',v:'2011'},{n:'2010',v:'2010'}]
  199. }],
  200. };
  201. }
  202. async function getVideos(url) {
  203. const html = await request(url);
  204. const $ = load(html);
  205. const cards = $('div.public-list-bj > a.public-list-exp')
  206. let videos = _.map(cards, (n) => {
  207. let id = n.attribs['href'];
  208. let name = n.attribs['title'] || $($(n).find('img')[0]).attr('alt').replaceAll('封面图', '');
  209. let pic = $($(n).find('img')[0]).attr('data-src');
  210. let remarks = $($(n).find('span.public-list-prb')[0]).text().trim();
  211. return {
  212. vod_id: id,
  213. vod_name: name,
  214. vod_pic: pic,
  215. vod_remarks: remarks,
  216. };
  217. });
  218. return videos;
  219. }
  220. async function getTx(url) {
  221. const html = await request(siteUrl + '/play/?url=' + url);
  222. const $ = load(html);
  223. for(const n of $('script')) {
  224. if($(n).text().indexOf('config = ') > 0) {
  225. let data = JSON.parse($(n).text().split('config = ')[1].split(';')[0]);
  226. let key = data['key'];
  227. let time = data['time'];
  228. const res = await request(siteUrl+'/play/API.php', {'url': url, 'time': time, 'key': key}, false);
  229. return JSON.parse(res)['url'];
  230. }
  231. }
  232. }
  233. async function getFx(url) {
  234. let res = await req(url, {
  235. method: 'get',
  236. headers: headers
  237. });
  238. let html = res.content;
  239. const $ = load(html);
  240. for(const n of $('script')) {
  241. if($(n).text().indexOf('result_v2') > 0) {
  242. let data = JSON.parse($(n).text().split('result_v2 = ')[1].split(';')[0])['data'];
  243. return getFxUrl(data);
  244. }
  245. }
  246. return url;
  247. }
  248. function getFxUrl(data) {
  249. let arr = data.split('').reverse();
  250. let res='';
  251. for(let i=0;i<arr.length;i = i+2) {
  252. let s = arr[i] + arr[i+1];
  253. let idx = parseInt(s, 0x10);
  254. res += String.fromCharCode(idx);
  255. }
  256. let index = (res.length - 0x7) / 0x2;
  257. let start = res.substring(0x0, index);
  258. let end = res.substring(index + 0x7);
  259. return start + end;
  260. }
  261. export function __jsEvalReturn() {
  262. return {
  263. init: init,
  264. home: home,
  265. homeVod: homeVod,
  266. category: category,
  267. detail: detail,
  268. play: play,
  269. search: search,
  270. };
  271. }