ikanbot_open2.js 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. import { Crypto, load, _ } from './lib/cat.js';
  2. let key = 'ikanbot';
  3. let url = 'https://www.ikanbot.com';
  4. let siteKey = '';
  5. let siteType = 0;
  6. const UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1';
  7. async function request(reqUrl, agentSp) {
  8. let res = await req(reqUrl, {
  9. method: 'get',
  10. headers: {
  11. 'User-Agent': agentSp || UA,
  12. 'referer': url
  13. },
  14. });
  15. return res.content;
  16. }
  17. // cfg = {skey: siteKey, ext: extend}
  18. async function init(cfg) {
  19. siteKey = cfg.skey;
  20. siteType = cfg.stype;
  21. }
  22. function getClass($) {
  23. const nav = $('ul.nav-pills:eq(1) > li > a');
  24. let tags = {
  25. key: 'tag',
  26. name: '标签',
  27. value: _.map(nav, (n) => {
  28. return { n: n.children[0].data, v: n.attribs.href };
  29. }),
  30. };
  31. tags['init'] = tags.value[0].v;
  32. const title = $('title:first').text().split('-')[0].substring(2);
  33. return { cls: { type_id: tags.value[0].v, type_name: title }, tags: [tags] };
  34. }
  35. async function home(filter) {
  36. let classes = [];
  37. let filterObj = {};
  38. for (const cate of ['/hot/index-movie-热门.html', '/hot/index-tv-热门.html']) {
  39. const html = await request(url + cate);
  40. const $ = load(html);
  41. const { cls, tags } = getClass($);
  42. classes.push(cls);
  43. filterObj[cls.type_id] = tags;
  44. }
  45. return JSON.stringify({
  46. class: classes,
  47. filters: filterObj,
  48. });
  49. }
  50. async function homeVod() {
  51. const html = await request(url);
  52. const $ = load(html);
  53. const items = $('div.v-list a.item');
  54. var jsBase = await js2Proxy(true, siteType, siteKey, 'img/', {});
  55. let videos = _.map(items, (item) => {
  56. const img = $(item).find('img:first')[0];
  57. return {
  58. vod_id: item.attribs.href,
  59. vod_name: img.attribs.alt,
  60. vod_pic: jsBase + base64Encode(img.attribs['data-src']),
  61. vod_remarks: '',
  62. };
  63. });
  64. return JSON.stringify({
  65. list: videos,
  66. });
  67. }
  68. async function category(tid, pg, filter, extend) {
  69. if (pg <= 0) pg = 1;
  70. const link = url + (extend.tag || tid).replace('.html', pg > 1 ? `-p-${pg}.html` : '.html');
  71. const html = await request(link);
  72. const $ = load(html);
  73. const items = $('div.v-list a.item');
  74. var jsBase = await js2Proxy(true, siteType, siteKey, 'img/', {});
  75. let videos = _.map(items, (item) => {
  76. const img = $(item).find('img:first')[0];
  77. return {
  78. vod_id: item.attribs.href,
  79. vod_name: img.attribs.alt,
  80. vod_pic: jsBase + base64Encode(img.attribs['data-src']),
  81. vod_remarks: '',
  82. };
  83. });
  84. const hasMore = $('div.page-more > a:contains(下一页)').length > 0;
  85. const pgCount = hasMore ? parseInt(pg) + 1 : parseInt(pg);
  86. return JSON.stringify({
  87. page: parseInt(pg),
  88. pagecount: pgCount,
  89. limit: 24,
  90. total: 24 * pgCount,
  91. list: videos,
  92. });
  93. }
  94. async function detail(id) {
  95. const html = await request(url + id);
  96. const $ = load(html);
  97. var jsBase = await js2Proxy(true, siteType, siteKey, 'img/', {});
  98. const detail = $('div.detail');
  99. const remarks = $('span#line-tips').text();
  100. let vod = {
  101. vod_id: id,
  102. vod_pic: jsBase + base64Encode($('div.item-root > img')[0].attribs['data-src']),
  103. vod_remarks: '',
  104. vod_content: remarks || '',
  105. vod_name: $(detail).find('h2').text().trim(),
  106. vod_year: $(detail).find('h3:nth-child(3)').text(),
  107. vod_area: $(detail).find('h3:nth-child(4)').text(),
  108. vod_actor: $(detail).find('h3:nth-child(5)').text(),
  109. };
  110. const token = getToken($);
  111. const res = await req(url + '/api/getResN?videoId=' + id.substring(id.lastIndexOf('/') + 1) + '&mtype=1&token=' + token, {
  112. headers: {
  113. Referer: 'play',
  114. 'User-Agent': UA,
  115. },
  116. });
  117. const list = JSON.parse(res.content).data.list;
  118. let playlist = {};
  119. let arr = []
  120. for (const l of list) {
  121. const flagData = JSON.parse(l.resData);
  122. for (const f of flagData) {
  123. const from = f.flag;
  124. const urls = f.url;
  125. if (!from || !urls) continue;
  126. if (playlist[from]) continue;
  127. playlist[from] = urls;
  128. }
  129. }
  130. for (var key in playlist) {
  131. if ('kuaikan' == key) {
  132. arr.push({
  133. flag: '快看',
  134. url: playlist[key],
  135. sort: 1
  136. })
  137. } else if ('bfzym3u8' == key) {
  138. arr.push({
  139. flag: '暴风',
  140. url: playlist[key],
  141. sort: 2
  142. })
  143. } else if ('ffm3u8' == key) {
  144. arr.push({
  145. flag: '非凡',
  146. url: playlist[key],
  147. sort: 3
  148. })
  149. } else if ('lzm3u8' == key) {
  150. arr.push({
  151. flag: '量子',
  152. url: playlist[key],
  153. sort: 4
  154. })
  155. } else {
  156. arr.push({
  157. flag: key,
  158. url: playlist[key],
  159. sort: 5
  160. })
  161. }
  162. }
  163. arr.sort((a, b) => a.sort - b.sort);
  164. let playFrom = [];
  165. let playList = [];
  166. arr.map(val => {
  167. playFrom.push(val.flag);
  168. playList.push(val.url);
  169. })
  170. vod.vod_play_from = playFrom.join("$$$");
  171. vod.vod_play_url = playList.join("$$$");
  172. return JSON.stringify({
  173. list: [vod],
  174. });
  175. }
  176. function getToken($) {
  177. const currentId = $('#current_id').val();
  178. let eToken = $('#e_token').val();
  179. if (!currentId || !eToken) return '';
  180. const idLength = currentId.length;
  181. const subId = currentId.substring(idLength - 4, idLength);
  182. let keys = [];
  183. for (let i = 0; i < subId.length; i++) {
  184. const curInt = parseInt(subId[i]);
  185. const splitPos = curInt % 3 + 1;
  186. keys[i] = eToken.substring(splitPos, splitPos + 8);
  187. eToken = eToken.substring(splitPos + 8, eToken.length);
  188. }
  189. return keys.join('');
  190. }
  191. function base64Encode(text) {
  192. return Crypto.enc.Base64.stringify(Crypto.enc.Utf8.parse(text));
  193. }
  194. function base64Decode(text) {
  195. return Crypto.enc.Utf8.stringify(Crypto.enc.Base64.parse(text));
  196. }
  197. async function proxy(segments, headers) {
  198. let what = segments[0];
  199. let url = base64Decode(segments[1]);
  200. if (what == 'img') {
  201. var resp = await req(url, {
  202. buffer: 2,
  203. headers: {
  204. Referer: url,
  205. 'User-Agent': UA,
  206. },
  207. });
  208. return JSON.stringify({
  209. code: resp.code,
  210. buffer: 2,
  211. content: resp.content,
  212. headers: resp.headers,
  213. });
  214. }
  215. return JSON.stringify({
  216. code: 500,
  217. content: '',
  218. });
  219. }
  220. async function play(flag, id, flags) {
  221. return JSON.stringify({
  222. parse: 0,
  223. url: id,
  224. });
  225. }
  226. async function search(wd, quick, pg) {
  227. if (pg <= 0 || typeof(pg) == 'undefined') pg = 1;
  228. const html = await request(url + '/search?q=' + wd + '&p=' + pg);
  229. const $ = load(html);
  230. const items = $('div.media');
  231. var jsBase = await js2Proxy(true, siteType, siteKey, 'img/', {});
  232. let videos = _.map(items, (item) => {
  233. const a = $(item).find('a:first')[0];
  234. const img = $(item).find('img:first')[0];
  235. const remarks = $($(item).find('span.label')[0]).text().trim();
  236. return {
  237. vod_id: a.attribs.href,
  238. vod_name: img.attribs.alt,
  239. vod_pic: jsBase + base64Encode(img.attribs['data-src']),
  240. vod_remarks: remarks || '',
  241. };
  242. });
  243. const hasMore = $('div.page-more > a:contains(下一页)').length > 0;
  244. const pgCount = hasMore ? parseInt(pg) + 1 : parseInt(pg);
  245. return JSON.stringify({
  246. page: parseInt(pg),
  247. pagecount: pgCount,
  248. list: videos,
  249. });
  250. }
  251. export function __jsEvalReturn() {
  252. return {
  253. init: init,
  254. home: home,
  255. homeVod: homeVod,
  256. category: category,
  257. detail: detail,
  258. play: play,
  259. proxy: proxy,
  260. search: search,
  261. };
  262. }