kunyu77_open.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. import { Crypto, dayjs, jinja2, Uri, _ } from './lib/cat.js';
  2. let key = 'kunyu77';
  3. let url = 'http://api.tyun77.cn';
  4. let device = {};
  5. let timeOffset = 0;
  6. let siteKey = '';
  7. let siteType = 0;
  8. async function request(reqUrl, agentSp) {
  9. let sj = dayjs().unix() - timeOffset;
  10. let uri = new Uri(reqUrl);
  11. uri.addQueryParam('pcode', '010110005');
  12. uri.addQueryParam('version', '2.1.6');
  13. uri.addQueryParam('devid', device.id);
  14. uri.addQueryParam('package', 'com.sevenVideo.app.android');
  15. uri.addQueryParam('sys', 'android');
  16. uri.addQueryParam('sysver', device.release);
  17. uri.addQueryParam('brand', device.brand);
  18. uri.addQueryParam('model', device.model.replaceAll(' ', '_'));
  19. uri.addQueryParam('sj', sj);
  20. let keys = [];
  21. for (var i = 0; i < uri.queryPairs.length; i++) {
  22. keys.push(uri.queryPairs[i][0]);
  23. }
  24. keys = _.sortBy(keys, function (name) {
  25. return name;
  26. });
  27. let tkSrc = uri.path();
  28. for (let k of keys) {
  29. let v = uri.getQueryParamValue(k);
  30. v = encodeURIComponent(v);
  31. tkSrc += v;
  32. }
  33. tkSrc += sj;
  34. tkSrc += 'XSpeUFjJ';
  35. console.log(tkSrc);
  36. let tk = Crypto.MD5(tkSrc).toString().toLowerCase();
  37. console.log(tk);
  38. let header = {
  39. 'user-agent': agentSp || 'okhttp/3.12.0',
  40. t: sj,
  41. TK: tk,
  42. };
  43. let res = await req(uri.toString(), {
  44. headers: header,
  45. });
  46. let serverTime = res.headers.date; // dart all response header key is lowercase
  47. let content = res.content;
  48. let serverTimeS = dayjs(serverTime).unix();
  49. timeOffset = dayjs().unix() - serverTimeS;
  50. // console.log(content);
  51. return content;
  52. }
  53. async function init(cfg) {
  54. siteKey = cfg.skey;
  55. siteType = cfg.stype;
  56. var deviceKey = 'device';
  57. var deviceInfo = await local.get(key, deviceKey);
  58. if (deviceInfo.length > 0) {
  59. try {
  60. device = JSON.parse(deviceInfo);
  61. } catch (error) {}
  62. }
  63. if (_.isEmpty(device)) {
  64. device = randDevice();
  65. device.id = randStr(32).toLowerCase();
  66. device.ua = 'Dalvik/2.1.0 (Linux; U; Android ' + device.release + '; ' + device.model + ' Build/' + device.buildId + ')';
  67. await local.set(key, deviceKey, JSON.stringify(device));
  68. }
  69. await request(url + '/api.php/provide/getDomain');
  70. await request(url + '/api.php/provide/config');
  71. await request(url + '/api.php/provide/checkUpgrade');
  72. await request(url + '/api.php/provide/channel');
  73. }
  74. async function home(filter) {
  75. let data = JSON.parse(await request(url + '/api.php/provide/filter')).data;
  76. let classes = [];
  77. let filterObj = {};
  78. let filterAll = [];
  79. for (const key in data) {
  80. classes.push({
  81. type_id: key,
  82. type_name: data[key][0].cat,
  83. });
  84. if (!filter) continue;
  85. try {
  86. let typeId = key.toString();
  87. if (_.isEmpty(filterAll)) {
  88. let filterData = JSON.parse(await request(url + '/api.php/provide/searchFilter?type_id=0&pagenum=1&pagesize=1')).data.conditions;
  89. // console.log(filterData);
  90. // 年份
  91. let year = {
  92. key: 'year',
  93. name: '年份',
  94. init: '',
  95. };
  96. let yearValues = [];
  97. yearValues.push({ n: '全部', v: '' });
  98. filterData.y.forEach((e) => {
  99. yearValues.push({ n: e.name, v: e.value });
  100. });
  101. year['value'] = yearValues;
  102. // 地区
  103. let area = {
  104. key: 'area',
  105. name: '地区',
  106. init: '',
  107. };
  108. let areaValues = [];
  109. areaValues.push({ n: '全部', v: '' });
  110. filterData.a.forEach((e) => {
  111. areaValues.push({ n: e.name, v: e.value });
  112. });
  113. area['value'] = areaValues;
  114. // 类型
  115. let type = {
  116. key: 'category',
  117. name: '类型',
  118. init: '',
  119. };
  120. let typeValues = [];
  121. typeValues.push({ n: '全部', v: '' });
  122. filterData.scat.forEach((e) => {
  123. typeValues.push({ n: e.name, v: e.value });
  124. });
  125. type['value'] = typeValues;
  126. filterAll.push(year, area, type);
  127. }
  128. if (!_.isEmpty(filterAll)) {
  129. filterObj[typeId] = filterAll;
  130. }
  131. } catch (e) {
  132. console.log(e);
  133. }
  134. }
  135. // console.log(classes);
  136. // console.log(filterObj);
  137. return JSON.stringify({
  138. class: classes,
  139. filters: filterObj,
  140. });
  141. }
  142. async function homeVod() {
  143. let data = JSON.parse(await request(url + '/api.php/provide/homeBlock?type_id=0')).data;
  144. let blocks = data.blocks;
  145. let videos = [];
  146. for (const block of blocks) {
  147. let name = block.block_name;
  148. if (name.indexOf('热播') >= 0) continue;
  149. let contents = block.contents;
  150. for (const content of contents) {
  151. videos.push({
  152. vod_id: content.id,
  153. vod_name: content.title,
  154. vod_pic: content.videoCover,
  155. vod_remarks: content.msg,
  156. });
  157. }
  158. }
  159. return JSON.stringify({
  160. list: videos,
  161. });
  162. }
  163. async function category(tid, pg, filter, extend) {
  164. let reqUrl = url + '/api.php/provide/searchFilter?type_id=' + tid + '&pagenum=' + pg + '&pagesize=24&';
  165. reqUrl += jinja2('year={{ext.year}}&category={{ext.category}}&area={{ext.area}}', { ext: extend });
  166. let data = JSON.parse(await request(reqUrl)).data;
  167. let videos = [];
  168. for (const vod of data.result) {
  169. videos.push({
  170. vod_id: vod.id,
  171. vod_name: vod.title,
  172. vod_pic: vod.videoCover,
  173. vod_remarks: vod.msg,
  174. });
  175. }
  176. return JSON.stringify({
  177. page: parseInt(data.page),
  178. pagecount: data.pagesize,
  179. limit: 24,
  180. total: data.total,
  181. list: videos,
  182. });
  183. }
  184. async function detail(id) {
  185. let data = JSON.parse(await request(url + '/api.php/provide/videoDetail?ids=' + id)).data;
  186. console.log(data);
  187. let vod = {
  188. vod_id: data.id,
  189. vod_name: data.videoName,
  190. vod_pic: data.videoCover,
  191. type_name: data.subCategory,
  192. vod_year: data.year,
  193. vod_area: data.area,
  194. vod_remarks: data.msg,
  195. vod_actor: data.actor,
  196. vod_director: data.director,
  197. vod_content: data.brief.trim(),
  198. };
  199. let episodes = JSON.parse(await request(url + '/api.php/provide/videoPlaylist?ids=' + id)).data.episodes;
  200. let playlist = {};
  201. for (const episode of episodes) {
  202. let playurls = episode.playurls;
  203. for (const playurl of playurls) {
  204. let from = playurl.playfrom;
  205. let t = formatPlayUrl(vod.vod_name, playurl.title);
  206. if (t.length == 0) t = playurl.title.trim();
  207. if (!playlist.hasOwnProperty(from)) {
  208. playlist[from] = [];
  209. }
  210. playlist[from].push(t + '$' + playurl.playurl);
  211. }
  212. }
  213. vod.vod_play_from = _.keys(playlist).join('$$$');
  214. let urls = _.values(playlist);
  215. let vod_play_url = [];
  216. for (const urlist of urls) {
  217. vod_play_url.push(urlist.join('#'));
  218. }
  219. vod.vod_play_url = vod_play_url.join('$$$');
  220. return JSON.stringify({
  221. list: [vod],
  222. });
  223. }
  224. async function play(flag, id, flags) {
  225. try {
  226. let data = JSON.parse(await request(url + '/api.php/provide/parserUrl?url=' + id + '&retryNum=0')).data;
  227. let playHeader = data.playHeader;
  228. let jxUrl = data.url;
  229. let res = await req(jxUrl, {
  230. headers: {
  231. 'user-agent': 'okhttp/3.12.0',
  232. },
  233. });
  234. let result = jsonParse(id, JSON.parse(res.content));
  235. result['parse'] = 0;
  236. if (playHeader) {
  237. result.header = _.merge(result.header, playHeader);
  238. }
  239. return JSON.stringify(result);
  240. } catch (e) {
  241. return JSON.stringify({
  242. parse: 0,
  243. url: id,
  244. });
  245. }
  246. }
  247. async function search(wd, quick, pg) {
  248. let page = pg || 1;
  249. if (page == 0) page = 1;
  250. let data = JSON.parse(await request(url + '/api.php/provide/searchVideo?searchName=' + wd + '&pg=' + page, 'okhttp/3.12.0'));
  251. let videos = [];
  252. for (const vod of data.data) {
  253. videos.push({
  254. vod_id: vod.id,
  255. vod_name: vod.videoName,
  256. vod_pic: vod.videoCover,
  257. vod_remarks: vod.msg,
  258. });
  259. }
  260. return JSON.stringify({
  261. page: page,
  262. pagecount: data.pages,
  263. list: videos,
  264. });
  265. }
  266. const charStr = 'abacdefghjklmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789';
  267. function randStr(len, withNum) {
  268. var _str = '';
  269. let containsNum = withNum === undefined ? true : withNum;
  270. for (var i = 0; i < len; i++) {
  271. let idx = _.random(0, containsNum ? charStr.length - 1 : charStr.length - 11);
  272. _str += charStr[idx];
  273. }
  274. return _str;
  275. }
  276. function randDevice() {
  277. return {
  278. brand: 'Huawei',
  279. model: 'HUAWEI Mate 20',
  280. release: '10',
  281. buildId: randStr(3, false).toUpperCase() + _.random(11, 99) + randStr(1, false).toUpperCase(),
  282. };
  283. }
  284. function formatPlayUrl(src, name) {
  285. return name
  286. .trim()
  287. .replaceAll(src, '')
  288. .replace(/<|>|《|》/g, '')
  289. .replace(/\$|#/g, ' ')
  290. .trim();
  291. }
  292. function jsonParse(input, json) {
  293. try {
  294. let url = json.url ?? '';
  295. if (url.startsWith('//')) {
  296. url = 'https:' + url;
  297. }
  298. if (!url.startsWith('http')) {
  299. return {};
  300. }
  301. let headers = json['headers'] || {};
  302. let ua = (json['user-agent'] || '').trim();
  303. if (ua.length > 0) {
  304. headers['User-Agent'] = ua;
  305. }
  306. let referer = (json['referer'] || '').trim();
  307. if (referer.length > 0) {
  308. headers['Referer'] = referer;
  309. }
  310. return {
  311. header: headers,
  312. url: url,
  313. };
  314. } catch (error) {
  315. console.log(error);
  316. }
  317. return {};
  318. }
  319. export function __jsEvalReturn() {
  320. return {
  321. init: init,
  322. home: home,
  323. homeVod: homeVod,
  324. category: category,
  325. detail: detail,
  326. play: play,
  327. search: search,
  328. };
  329. }