360kan_open.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. import { Crypto, load, _ } from './lib/cat.js';
  2. let siteUrl ='https://www.360kan.com';
  3. let siteKey = '';
  4. let siteType = 0;
  5. let headers = {
  6. 'User-Agent': '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. 'Referer': siteUrl + '/'
  8. };
  9. async function request(reqUrl, postData, post) {
  10. let res = await req(reqUrl, {
  11. method: post ? 'post' : 'get',
  12. headers: headers,
  13. data: postData || {},
  14. postType: post ? 'form' : '',
  15. });
  16. let content = res.content;
  17. return content;
  18. }
  19. async function init(cfg) {
  20. siteKey = cfg.skey;
  21. siteType = cfg.stype;
  22. if (cfg.ext) {
  23. siteUrl = cfg.ext;
  24. }
  25. }
  26. async function home(filter) {
  27. let classes = [{
  28. type_id: '1',
  29. type_name: '电影',
  30. },{
  31. type_id: '2',
  32. type_name: '电视剧',
  33. },{
  34. type_id: '3',
  35. type_name: '综艺',
  36. },{
  37. type_id: '4',
  38. type_name: '动漫',
  39. }];
  40. let filterObj = genFilterObj();
  41. return JSON.stringify({
  42. class: classes,
  43. filters: filterObj
  44. });
  45. }
  46. async function homeVod() {
  47. }
  48. async function category(tid, pg, filter, ext) {
  49. if (!pg) pg = 1;
  50. if (pg <= 0) pg = 1;
  51. let url = `https://api.web.360kan.com/v1/filter/list?catid=${tid}&rank=rankhot&cat=${ext['cat']||''}&year=${ext['year']||''}&area=${ext['area']||''}&act=&size=35`
  52. let res = JSON.parse(await request(url)).data
  53. let videos = _.map(res.movies, n => {
  54. return {
  55. vod_id: tid + '_' + n.id,
  56. vod_name: n.title,
  57. vod_pic: 'https:' + n.cdncover,
  58. vod_remarks: n.upinfo
  59. }
  60. })
  61. return JSON.stringify({
  62. list: videos,
  63. page: pg,
  64. total: res.total,
  65. limit: 35
  66. });
  67. }
  68. async function detail(id) {
  69. try {
  70. let tid = id.split('_')[0];
  71. let pid = id.split('_')[1];
  72. let url = `https://api.web.360kan.com/v1/detail?cat=${tid}&id=${pid}&site=`
  73. let res = JSON.parse(await request(url)).data;
  74. const video = {
  75. vod_play_from: res.playlink_sites.join('$$$'),
  76. //vod_play_url: playUrls.join('$$$'),
  77. vod_content: res.description,
  78. vod_director: res.director.join(' '),
  79. vod_actor: res.actor.join(' '),
  80. };
  81. let playUrls = [];
  82. for(const name of res.playlink_sites) {
  83. if(res.allepidetail) {
  84. if(res.allepidetail[name]) {
  85. let str = _.map(res.allepidetail[name], item => {
  86. return item.playlink_num + '$' + item.url;
  87. }).join('#');
  88. playUrls.push(str);
  89. } else {
  90. url = url + name;
  91. res = JSON.parse(await request(url)).data;
  92. playUrls.push(_.map(res.allepidetail[name], item => {
  93. return item.playlink_num + '$' + item.url;
  94. }).join('#'));
  95. }
  96. } else if(res.playlinksdetail[name]) {
  97. playUrls.push('播放$'+res.playlinksdetail[name].default_url);
  98. }
  99. };
  100. video.vod_play_url = playUrls.join('$$$');
  101. const list = [video];
  102. const result = { list };
  103. return JSON.stringify(result);
  104. } catch (e) {
  105. console.log('err', e);
  106. }
  107. return null;
  108. }
  109. async function search(wd, quick, pg) {
  110. let url = `https://api.so.360kan.com/index?force_v=1&kw=${encodeURIComponent(wd)}&v_ap=1&tab=all`;
  111. const res = JSON.parse(await request(url)).data;
  112. let videos = _.map(res.longData.rows, (n) => {
  113. return {
  114. vod_id: n.cat_id + '_' + n.en_id,
  115. vod_name: n.titleTxt,
  116. vod_pic: n.cover,
  117. vod_remarks: n.coverInfo.txt,
  118. };
  119. });
  120. return JSON.stringify({
  121. list: videos,
  122. });
  123. }
  124. async function play(flag, id, flags) {
  125. let playUrl = await xmjiexi(id);
  126. return JSON.stringify({
  127. parse: 0,
  128. url: playUrl,
  129. header: {
  130. 'User-Agent': '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',
  131. "Origin": 'https://jx.xmflv.com',
  132. }
  133. });
  134. }
  135. function genFilterObj() {
  136. return {
  137. '2': [{'key': 'cat', 'name': '类型', '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': '青春'},{'n': '家庭', 'v': '家庭'}, {'n': '动作', 'v': '动作'}, {'n': '情景', 'v': '情景'}, {'n': '武侠', 'v': '武侠'}, {'n': '科幻', 'v': '科幻'}]},
  138. {'key': 'area', 'name': '地区', 'value': [{'n': '全部', 'v': ''}, {'n': '内地', 'v': '内地'}, {'n': '香港', 'v': '香港'}, {'n': '台湾', 'v': '台湾'}, {'n': '美国', 'v': '美国'}, {'n': '韩国', 'v': '韩国'},{'n': '日本', 'v': '日本'}]},
  139. {'key': 'year', 'name': '年份', 'value': [{'n': '全部', 'v': ''}, {'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'}]}
  140. ],
  141. '1': [{'key': 'cat', 'name': '类型', 'value': [{'n': '全部', 'v': '2'}, {'n': '喜剧', 'v': '喜剧'}, {'n': '爱情', 'v': '爱情'},{'n': '动作', 'v': '动作'}, {'n': '恐怖', 'v': '恐怖'}, {'n': '科幻', 'v': '科幻'}, {'n': '剧情', 'v': '剧情'},{'n': '犯罪', 'v': '犯罪'}, {'n': '奇幻', 'v': '奇幻'}, {'n': '战争', 'v': '战争'}, {'n': '悬疑', 'v': '悬疑'},{'n': '动画', 'v': '动画'}, {'n': '文艺', 'v': '文艺'}]},
  142. {'key': 'area', 'name': '地区', 'value': [{'n': '全部', 'v': ''}, {'n': '内地', 'v': '内地'}, {'n': '台湾', 'v': '台湾'}, {'n': '香港', 'v': '香港'}, {'n': '韩国', 'v': '韩国'}, {'n': '日本', 'v': '日本'}, {'n': '美国', 'v': '美国'}, {'n': '泰国', 'v': '泰国'}, {'n': '英国', 'v': '英国'}, {'n': '新加坡', 'v': '新加坡'}, {'n': '其他', 'v': '其他'}]},
  143. {'key': 'year', 'name': '年份', 'value': [{'n': '全部', 'v': ''}, {'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'}, {'n': '2009', 'v': '2009'}, {'n': '2008', 'v': '2008'}, {'n': '2006', 'v': '2006'}, {'n': '2005', 'v': '2005'}]}
  144. ]
  145. };
  146. }
  147. async function xmjiexi(url) {
  148. let t=new Date().getTime();
  149. //console.log(t+url)
  150. let encData = sign(Crypto.MD5(t+url).toString().toLowerCase());
  151. //console.log(encData);
  152. let res = JSON.parse((await req('http://124.223.52.167:8088/jiexi', {
  153. method: 'post',
  154. headers: {
  155. 'Content-Type': 'application/json',
  156. },
  157. data: {
  158. "wap": "1",
  159. "time": String(t),
  160. "url": url,
  161. "key": encData,
  162. },
  163. postType: ''
  164. })).content);
  165. let playUrl = aesDecode(res.url, res.aes_key, res.aes_iv);
  166. return playUrl;
  167. }
  168. //aes解密
  169. function aesDecode(str, keyStr, ivStr) {
  170. const key = Crypto.enc.Utf8.parse(keyStr);
  171. var bytes = Crypto.AES.decrypt(str, key, {
  172. iv: Crypto.enc.Utf8.parse(ivStr),
  173. mode: Crypto.mode.CBC,
  174. padding: Crypto.pad.Pkcs7
  175. });
  176. return bytes.toString(Crypto.enc.Utf8);
  177. }
  178. function sign(a) {
  179. var b = Crypto.MD5(a);
  180. //console.log(b.toString())
  181. var c = Crypto.enc.Utf8.parse(b);
  182. var d = Crypto.enc.Utf8.parse('3cccf88181408f19');
  183. var e = Crypto.AES.encrypt(a, c, {
  184. iv: d,
  185. mode: Crypto.mode.CBC,
  186. padding: Crypto.pad.ZeroPadding
  187. });
  188. return e.toString()
  189. }
  190. export function __jsEvalReturn() {
  191. return {
  192. init: init,
  193. home: home,
  194. homeVod: homeVod,
  195. category: category,
  196. detail: detail,
  197. play: play,
  198. search: search,
  199. };
  200. }