From 721420eaa6de472f0c29f9f931f4a31d00659016 Mon Sep 17 00:00:00 2001
From: dxawi <107306227+dxawi@users.noreply.github.com>
Date: Thu, 14 Sep 2023 18:35:21 +0800
Subject: [PATCH] Add files via upload
---
cat/Bili.js | 678 +++++++++++++++++++++++++++++++++++++++
cat/ikanbot-not-async.js | 220 +++++++++++++
cat/ikanbot_open.js | 140 +++++---
3 files changed, 993 insertions(+), 45 deletions(-)
create mode 100644 cat/Bili.js
create mode 100644 cat/ikanbot-not-async.js
diff --git a/cat/Bili.js b/cat/Bili.js
new file mode 100644
index 0000000..69794a4
--- /dev/null
+++ b/cat/Bili.js
@@ -0,0 +1,678 @@
+import { Crypto, jinja2, _ } from 'assets://js/lib/cat.js';
+
+let siteKey = '';
+let siteType = 0;
+
+let cookie = '';
+let login = '';
+let vip = false;
+let extendObj = {};
+let bili_jct = '';
+let vod_audio_id = {
+ 30280: 192000,
+ 30232: 132000,
+ 30216: 64000,
+};
+
+let vod_codec = {
+ // 13: 'AV1',
+ 12: 'HEVC',
+ 7: 'AVC',
+};
+
+const UA = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36';
+
+async function request(reqUrl, ua, buffer) {
+ let res = await req(reqUrl, {
+ method: 'get',
+ headers: ua ? ua : { 'User-Agent': UA },
+ timeout: 60000,
+ buffer: buffer ? 1 : 0,
+ });
+ return res.content;
+}
+
+async function post(reqUrl, postData, ua, posttype) {
+ let res = await req(reqUrl, {
+ method: 'post',
+ headers: ua ? ua : { 'User-Agent': UA },
+ data: postData,
+ timeout: 60000,
+ postType: posttype,
+ });
+ return res.content;
+}
+
+function getHeaders() {
+ const headers = {
+ 'User-Agent': UA,
+ };
+ if (!_.isEmpty(cookie)) {
+ headers.cookie = cookie;
+ }
+ return headers;
+}
+
+async function getCookie() {
+ let result = await req('https://www.bilibili.com', {
+ method: 'get',
+ headers: { 'User-Agent': UA },
+ timeout: 60000,
+ });
+ const setCookieHeaders = result.headers['set-cookie'];
+ cookie = setCookieHeaders.map((kk) => kk.split(';')[0] + ';').join('');
+}
+
+async function init(cfg) {
+ siteKey = cfg.skey;
+ siteType = cfg.stype;
+ let extend = cfg.ext;
+
+ if (typeof cfg.ext == 'string') {
+ if (cfg.ext.indexOf('http') == 0) {
+ const res = await req(cfg.ext, getHeaders());
+ cfg.ext = JSON.parse(res.content);
+ } else {
+ cfg.ext = {type: cfg.ext};
+ }
+ extend = cfg.ext;
+ }
+
+ if (cfg.ext.hasOwnProperty('categories'))
+ extend = cfg.ext.categories;
+ else if (cfg.ext.hasOwnProperty('type'))
+ extend = cfg.ext.type;
+
+ if (extend == '')
+ extend = '抖音热歌$$$经典无损音乐合集$$$超清MV$$$Java$$$Android';
+
+
+ if (cfg.ext.hasOwnProperty('cookie')) cookie = cfg.ext.cookie;
+
+ // 获取csrf
+ const cookies = cookie.split(';');
+ cookies.forEach(cookie => {
+ if (cookie.includes('bili_jct')) {
+ bili_jct = cookie.split('=')[1];
+ }
+ });
+
+ if (_.isEmpty(cookie)) await getCookie();
+ let result = JSON.parse(await request('https://api.bilibili.com/x/web-interface/nav', getHeaders()));
+ login = result.data.isLogin;
+ vip = result.data.vipStatus;
+ const ext = extend.split('$$$');
+ console.log("ext: " + ext);
+ const jsonData = [
+ {
+ key: 'order',
+ name: '排序',
+ value: [
+ { n: '综合排序', v: '0' },
+ { n: '最多点击', v: 'click' },
+ { n: '最新发布', v: 'pubdate' },
+ { n: '最多弹幕', v: 'dm' },
+ { n: '最多收藏', v: 'stow' },
+ ],
+ },
+ {
+ key: 'duration',
+ name: '时长',
+ value: [
+ { n: '全部时长', v: '0' },
+ { n: '60分钟以上', v: '4' },
+ { n: '30~60分钟', v: '3' },
+ { n: '10~30分钟', v: '2' },
+ { n: '10分钟以下', v: '1' },
+ ],
+ },
+ ];
+ const newarr = [];
+ const d = {};
+ const sc = {
+ type_name: "首页",
+ type_id: "首页",
+ land: 1,
+ ratio: 1.33,
+ }
+ // newarr.push(sc);
+ for (const kk of ext) {
+ const cate = kk.split('#');
+ const value = [];
+ for (const item of cate) {
+ const kkk = item.indexOf('$') > 0 ? item : item + "$" + item;
+ const val = kkk.split('$');
+ value.push({n: val[0], v: val[1]});
+ }
+ const c = {
+ type_name: value[0].n,
+ type_id: value[0].v,
+ land: 1,
+ ratio: 1.33,
+ type_flag: '0-0-H'
+ };
+ newarr.push(c);
+ const filter = [];
+ if (value.length > 1) {
+ filter.push(
+ {
+ key: 'tid',
+ name: '分类',
+ value: value
+ }
+ );
+ }
+ filter.push(jsonData[0]);
+ filter.push(jsonData[1]);
+ d[value[0].v] = filter;
+ }
+ if (!_.isEmpty(bili_jct)) {
+ const hc = {
+ type_name: "历史记录",
+ type_id: "历史记录",
+ land: 1,
+ ratio: 1.33,
+ }
+ newarr.push(hc);
+ }
+ extendObj = {
+ classes: newarr,
+ filter: d,
+ };
+}
+
+function home(filter) {
+ try {
+ const jSONObject = {
+ class: extendObj.classes,
+ type_flag: '0-0-H'
+ };
+ if (filter) {
+ jSONObject.filters = extendObj.filter;
+ }
+ return JSON.stringify(jSONObject);
+ } catch (e) {
+ return '';
+ }
+}
+
+async function homeVod() {
+ return category('白噪音', 1, false, {});
+ // try {
+ // const list = [];
+ // const url = 'https://api.bilibili.com/x/web-interface/index/top/rcmd?ps=14&fresh_idx=1&fresh_idx_1h=1';
+
+ // const response = await request(url, getHeaders());
+ // const responseData = JSON.parse(response);
+ // const vods = responseData.data.item;
+
+ // for (const item of vods) {
+ // const vod = {};
+ // let imageUrl = item.pic;
+ // if (imageUrl.startsWith('//')) {
+ // imageUrl = 'https:' + imageUrl;
+ // }
+ // let cd = getFullTime(item.duration);
+
+ // vod.vod_id = item.bvid;
+ // vod.vod_name = removeTags(item.title);
+ // vod.vod_pic = imageUrl;
+ // vod.vod_remarks = cd;
+ // vod.style = {
+ // type: 'rect',
+ // ratio: 1.33,
+ // },
+ // list.push(vod);
+ // }
+
+ // const result = { list: list };
+ // return JSON.stringify(result);
+ // } catch (e) { }
+}
+
+async function category(tid, page, filter, ext) {
+ if (page < 1) page = 1;
+ try {
+ if (Object.keys(ext).length > 0 && ext.hasOwnProperty('tid') && ext['tid'].length > 0) {
+ tid = ext['tid'];
+ }
+ let url = '';
+ url = `https://api.bilibili.com/x/web-interface/search/type?search_type=video&keyword=${encodeURIComponent(tid)}`;
+
+ if (Object.keys(ext).length > 0) {
+ for (const k in ext) {
+ if (k == 'tid') {
+ continue;
+ }
+ url += `&${encodeURIComponent(k)}=${encodeURIComponent(ext[k])}`;
+ }
+ }
+
+ url += `&page=${encodeURIComponent(page)}`;
+
+ if (tid == "首页") {
+ url = "https://api.bilibili.com/x/web-interface/index/top/rcmd?ps=14&fresh_idx=" + page + "&fresh_idx_1h=" + page;
+ } else if (tid == "历史记录") {
+ url = "https://api.bilibili.com/x/v2/history?pn=" + page;
+ }
+
+ const data = JSON.parse(await request(url, getHeaders())).data;
+ let items = data.result;
+ if (tid == "首页") {
+ items = data.item;
+ } else if (tid == "历史记录") {
+ items = data;
+ }
+
+ const videos = [];
+ for (const item of items) {
+ const video = {};
+ let pic = item.pic;
+ if (pic.startsWith('//')) {
+ pic = 'https:' + pic;
+ }
+ let cd = getFullTime(item.duration);
+
+ video.vod_remarks = cd;
+ video.vod_id = item.bvid;
+ video.vod_name = removeTags(item.title);
+ video.vod_pic = pic;
+
+ video.style = {
+ type: 'rect',
+ ratio: 1.33,
+ },
+ videos.push(video);
+ }
+
+ const result = {
+ page: page,
+ pagecount: data.numPages ?? (page + 1),
+ limit: videos.length,
+ total: videos.length * (page + 1),
+ list: videos,
+ };
+
+ return JSON.stringify(result);
+ } catch (e) { }
+ return null;
+}
+
+async function detail(ids) {
+ try {
+ const bvid = ids;
+ const detailUrl = `https://api.bilibili.com/x/web-interface/view?bvid=${bvid}`;
+
+ const detailData = JSON.parse(await request(detailUrl, getHeaders())).data;
+ // 记录历史
+ if (!_.isEmpty(bili_jct)) {
+ const historyReport = 'https://api.bilibili.com/x/v2/history/report';
+ let dataPost = {
+ aid: detailData.aid,
+ cid: detailData.cid,
+ csrf: bili_jct,
+ }
+ await post(historyReport, dataPost, getHeaders(), 'form');
+ }
+ let cd = getFullTime(detailData.duration);
+ const aid = detailData.aid;
+ const video = {
+ vod_id: bvid,
+ vod_name: detailData.title,
+ vod_pic: detailData.pic,
+ type_name: detailData.tname,
+ vod_year: '',
+ vod_area: '',
+ vod_remarks: cd,
+ vod_actor: '',
+ vod_director: '',
+ vod_content: detailData.desc,
+ };
+
+ const playurldata = 'https://api.bilibili.com/x/player/playurl?avid=' + aid + '&cid=' + detailData.cid + '&qn=127&fnval=4048&fourk=1';
+ const playurldatas = JSON.parse(await request(playurldata, getHeaders()));
+
+ const playurldatalist = playurldatas.data;
+ const accept_quality = playurldatalist.accept_quality;
+ const accept_description = playurldatalist.accept_description;
+ const qualitylist = [];
+ const descriptionList = [];
+
+ for (let i = 0; i < accept_quality.length; i++) {
+ if (!vip) {
+ if (!login) {
+ if (accept_quality[i] > 32) continue;
+ } else {
+ if (accept_quality[i] > 80) continue;
+ }
+ }
+ descriptionList.push(base64Encode(accept_description[i]));
+ qualitylist.push(accept_quality[i]);
+ }
+
+ let treeMap = {};
+ const jSONArray = detailData.pages;
+ let playList = [];
+ for (let j = 0; j < jSONArray.length; j++) {
+ const jSONObject6 = jSONArray[j];
+ const cid = jSONObject6.cid;
+ const title = jSONObject6.part;
+ const duration = jSONObject6.duration;
+ const playUrl = '[' + secondsToTime(duration) + '] ' + title + '$' + aid + '+' + cid + '+' + qualitylist.join(':') + '+' + descriptionList.join(':');
+ playList.push(playUrl);
+ }
+ treeMap['dash'] = playList.join('#');
+ treeMap['mp4'] = playList.join('#');
+
+ const relatedUrl = 'https://api.bilibili.com/x/web-interface/archive/related?bvid=' + bvid;
+ const relatedData = JSON.parse(await request(relatedUrl, getHeaders())).data;
+ playList = [];
+ for (let j = 0; j < relatedData.length; j++) {
+ const jSONObject6 = relatedData[j];
+ const cid = jSONObject6.cid;
+ const title = jSONObject6.title;
+ const aaid = jSONObject6.aid;
+ const playUrl = title + '$' + aaid + '+' + cid + '+' + qualitylist.join(':') + '+' + descriptionList.join(':');
+ playList.push(playUrl);
+ }
+ treeMap['相关'] = playList.join('#');
+
+ video.vod_play_from = Object.keys(treeMap).join("$$$");
+ video.vod_play_url = Object.values(treeMap).join("$$$");
+
+ // console.log("====>video: " + JSON.stringify(video));
+
+ const list = [video];
+ const result = { list };
+ return JSON.stringify(result);
+ } catch (e) { }
+ return null;
+}
+
+async function play(flag, id, flags) {
+ try {
+ const playHeaders = { Referer: 'https://www.bilibili.com', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36' };
+ const ids = id.split('+');
+ const aid = ids[0];
+ const cid = ids[1];
+ const qualityIds = ids[2].split(':');
+ const qualityName = ids[3].split(':');
+ if (flag == 'dash' || flag == '相关') {
+ // dash mpd 代理
+ const js2Base = await js2Proxy(true, siteType, siteKey, 'dash/', {});
+ let urls = [];
+ for (let i = 0; i < qualityIds.length; i++) {
+ urls.push(base64Decode(qualityName[i]), js2Base + base64Encode(aid + '+' + cid + '+' + qualityIds[i]));
+ }
+ return JSON.stringify({
+ parse: 0,
+ url: urls,
+ header: playHeaders,
+ });
+ } else if (flag == 'mp4') {
+ // 直链
+ let urls = [];
+ for (let i = 0; i < qualityIds.length; i++) {
+ const url = `https://api.bilibili.com/x/player/playurl?avid=${aid}&cid=${cid}&qn=${qualityIds[i]}&fourk=1`;
+ const resp = JSON.parse(await request(url, getHeaders()));
+ const data = resp.data;
+ if (data.quality != qualityIds[i]) continue;
+ let durl = data.durl[0].url;
+ urls.push(base64Decode(qualityName[i]), durl);
+ }
+
+ return JSON.stringify({
+ parse: 0,
+ url: urls,
+ header: playHeaders,
+ });
+ } else {
+ // 音频外挂
+ let urls = [];
+ let audios = [];
+ for (let i = 0; i < qualityIds.length; i++) {
+ const url = `https://api.bilibili.com/x/player/playurl?avid=${aid}&cid=${cid}&qn=${qualityIds[i]}&fnval=4048&fourk=1`;
+ let resp = JSON.parse(await request(url, getHeaders()));
+ const dash = resp.data.dash;
+ const video = dash.video;
+ const audio = dash.audio;
+ for (let j = 0; j < video.length; j++) {
+ const dashjson = video[j];
+ if (dashjson.id == qualityIds[i]) {
+ for (const key in vod_codec) {
+ if (dashjson.codecid == key) {
+ urls.push(base64Decode(qualityName[i]) + ' ' + vod_codec[key], dashjson.baseUrl);
+ }
+ }
+ }
+ }
+ if (audios.length == 0) {
+ for (let j = 0; j < audio.length; j++) {
+ const dashjson = audio[j];
+ for (const key in vod_audio_id) {
+ if (dashjson.id == key) {
+ audios.push({
+ title: _.floor(parseInt(vod_audio_id[key]) / 1024) + 'Kbps',
+ bit: vod_audio_id[key],
+ url: dashjson.baseUrl,
+ });
+ }
+ }
+ }
+ audios = _.sortBy(audios, 'bit');
+ }
+ }
+
+ return JSON.stringify({
+ parse: 0,
+ url: urls,
+ extra: {
+ audio: audios,
+ },
+ header: playHeaders,
+ });
+ }
+ } catch (e) { }
+ return null;
+}
+
+async function search(key, quick, pg) {
+ let page = pg || 1;
+ if (page == 0) page = 1;
+ try {
+ const ext = {
+ duration: '0',
+ };
+ let resp = JSON.parse(await category(key, page, true, ext));
+ const catVideos = resp.list;
+ const pageCount = resp.pagecount;
+ const videos = [];
+ for (let i = 0; i < catVideos.length; ++i) {
+ videos.push(catVideos[i]);
+ }
+ const result = {
+ page: page,
+ pagecount: pageCount,
+ land: 1,
+ ratio: 1.33,
+ list: videos,
+ };
+ return JSON.stringify(result);
+ } catch (e) { }
+ return null;
+}
+
+async function proxy(segments, headers) {
+ let what = segments[0];
+ let url = base64Decode(segments[1]);
+ if (what == 'dash') {
+ const ids = url.split('+');
+ const aid = ids[0];
+ const cid = ids[1];
+ const str5 = ids[2];
+ const urls = `https://api.bilibili.com/x/player/playurl?avid=${aid}&cid=${cid}&qn=${str5}&fnval=4048&fourk=1`;
+ let videoList = '';
+ let audioList = '';
+
+ let resp = JSON.parse(await request(urls, getHeaders()));
+ const dash = resp.data.dash;
+ const video = dash.video;
+ const audio = dash.audio;
+
+ for (let i = 0; i < video.length; i++) {
+ // if (i > 0) continue; // 只取一个
+ const dashjson = video[i];
+ if (dashjson.id == str5) {
+ videoList += getDashMedia(dashjson);
+ }
+ }
+
+ for (let i = 0; i < audio.length; i++) {
+ // if (i > 0) continue;
+ const ajson = audio[i];
+ for (const key in vod_audio_id) {
+ if (ajson.id == key) {
+ audioList += getDashMedia(ajson);
+ }
+ }
+ }
+
+ let mpd = getDash(resp, videoList, audioList);
+
+ return JSON.stringify({
+ code: 200,
+ content: mpd,
+ headers: {
+ 'Content-Type': 'application/dash+xml',
+ },
+ });
+ }
+ return JSON.stringify({
+ code: 500,
+ content: '',
+ });
+}
+
+function getDashMedia(dash) {
+ try {
+ let qnid = dash.id;
+ const codecid = dash.codecid;
+ const media_codecs = dash.codecs;
+ const media_bandwidth = dash.bandwidth;
+ const media_startWithSAP = dash.startWithSap;
+ const media_mimeType = dash.mimeType;
+ const media_BaseURL = dash.baseUrl.replace(/&/g, '&');
+ const media_SegmentBase_indexRange = dash.SegmentBase.indexRange;
+ const media_SegmentBase_Initialization = dash.SegmentBase.Initialization;
+ const mediaType = media_mimeType.split('/')[0];
+ let media_type_params = '';
+
+ if (mediaType == 'video') {
+ const media_frameRate = dash.frameRate;
+ const media_sar = dash.sar;
+ const media_width = dash.width;
+ const media_height = dash.height;
+ media_type_params = `height='${media_height}' width='${media_width}' frameRate='${media_frameRate}' sar='${media_sar}'`;
+ } else if (mediaType == 'audio') {
+ for (const key in vod_audio_id) {
+ if (qnid == key) {
+ const audioSamplingRate = vod_audio_id[key];
+ media_type_params = `numChannels='2' sampleRate='${audioSamplingRate}'`;
+ }
+ }
+ }
+ qnid += '_' + codecid;
+
+ return `
+
+
+ ${media_BaseURL}
+
+
+
+
+ `;
+ } catch (e) {
+ // Handle exceptions here
+ }
+}
+
+function getDash(ja, videoList, audioList) {
+ const duration = ja.data.dash.duration;
+ const minBufferTime = ja.data.dash.minBufferTime;
+ return `
+
+ ${videoList}
+ ${audioList}
+
+ `;
+}
+
+
+function base64Encode(text) {
+ return Crypto.enc.Base64.stringify(Crypto.enc.Utf8.parse(text));
+}
+
+function base64Decode(text) {
+ return Crypto.enc.Utf8.stringify(Crypto.enc.Base64.parse(text));
+}
+
+
+
+function removeTags(input) {
+ return input.replace(/<[^>]*>/g, '');
+}
+
+function getFullTime(numberSec) {
+ let totalSeconds = '';
+ try {
+ var timeParts = numberSec.split(":");
+ var min = parseInt(timeParts[0]);
+ var sec = parseInt(timeParts[1]);
+ totalSeconds = min * 60 + sec;
+ } catch (e) {
+ totalSeconds = parseInt(numberSec);
+ }
+ if (isNaN(totalSeconds)) {
+ return '无效输入';
+ }
+ if (totalSeconds >= 3600) {
+ const hours = Math.floor(totalSeconds / 3600);
+ const remainingSecondsAfterHours = totalSeconds % 3600;
+ const minutes = Math.floor(remainingSecondsAfterHours / 60);
+ const seconds = remainingSecondsAfterHours % 60;
+ return `${hours}小时 ${minutes}分钟 ${seconds}秒`;
+ } else {
+ const minutes = Math.floor(totalSeconds / 60);
+ const seconds = totalSeconds % 60;
+ return `${minutes}分钟 ${seconds}秒`;
+ }
+}
+
+function secondsToTime(seconds) {
+ var hours = Math.floor(seconds / 3600);
+ var minutes = Math.floor((seconds - (hours * 3600)) / 60);
+ var seconds = seconds - (hours * 3600) - (minutes * 60);
+
+ // round seconds
+ seconds = Math.round(seconds * 100) / 100
+
+ var result = (hours < 10 ? "0" + hours : hours);
+ result += ":" + (minutes < 10 ? "0" + minutes : minutes);
+ result += ":" + (seconds < 10 ? "0" + seconds : seconds);
+ return result;
+}
+
+export function __jsEvalReturn() {
+ return {
+ init: init,
+ home: home,
+ homeVod: homeVod,
+ category: category,
+ detail: detail,
+ play: play,
+ proxy: proxy,
+ search: search,
+ };
+}
+
diff --git a/cat/ikanbot-not-async.js b/cat/ikanbot-not-async.js
new file mode 100644
index 0000000..056aed3
--- /dev/null
+++ b/cat/ikanbot-not-async.js
@@ -0,0 +1,220 @@
+import { Crypto, load, _ } from './lib/cat.js';
+
+let key = 'ikanbot';
+let url = 'https://www.ikanbot.com';
+let siteKey = '';
+let siteType = 0;
+
+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';
+
+function request(reqUrl, agentSp) {
+ let res = req(reqUrl, {
+ method: 'get',
+ headers: {
+ 'User-Agent': agentSp || UA,
+ 'referer': url
+ },
+ });
+ return res.content;
+}
+
+// cfg = {skey: siteKey, ext: extend}
+function init(cfg) {
+ siteKey = cfg.skey;
+ siteType = cfg.stype;
+}
+
+function getClass($) {
+ const nav = $('ul.nav-pills:eq(1) > li > a');
+ let tags = {
+ key: 'tag',
+ name: '标签',
+ value: _.map(nav, (n) => {
+ return { n: n.children[0].data, v: n.attribs.href };
+ }),
+ };
+ tags['init'] = tags.value[0].v;
+ const title = $('title:first').text().split('-')[0].substring(2);
+ return { cls: { type_id: tags.value[0].v, type_name: title }, tags: [tags] };
+}
+
+function home(filter) {
+ let classes = [];
+ let filterObj = {};
+ for (const cate of ['/hot/index-movie-热门.html', '/hot/index-tv-热门.html']) {
+ const html = request(url + cate);
+ const $ = load(html);
+ const { cls, tags } = getClass($);
+ classes.push(cls);
+ filterObj[cls.type_id] = tags;
+ }
+ return JSON.stringify({
+ class: classes,
+ filters: filterObj,
+ });
+}
+
+function homeVod() {
+ return '{}';
+}
+
+function category(tid, pg, filter, extend) {
+ if (pg <= 0) pg = 1;
+ const link = url + (extend.tag || tid).replace('.html', pg > 1 ? `-p-${pg}.html` : '.html');
+ const html = request(link);
+ const $ = load(html);
+ const items = $('div.v-list a.item');
+ // var jsBase = js2Proxy(true, siteType, siteKey, 'img/', {});
+ // console.log(jsBase);
+ let videos = _.map(items, (item) => {
+ const img = $(item).find('img:first')[0];
+ // console.log(jsBase + base64Encode(img.attribs['data-src']));
+ return {
+ vod_id: item.attribs.href,
+ vod_name: img.attribs.alt,
+ // vod_pic: jsBase + base64Encode(img.attribs['data-src']),
+ vod_pic: img.attribs['data-src'] + '@Referer=' + url + '@User-Agent=' + UA,
+ vod_remarks: '',
+ };
+ });
+ const hasMore = $('div.page-more > a:contains(下一页)').length > 0;
+ const pgCount = hasMore ? parseInt(pg) + 1 : parseInt(pg);
+ return JSON.stringify({
+ page: parseInt(pg),
+ pagecount: pgCount,
+ limit: 24,
+ total: 24 * pgCount,
+ list: videos,
+ });
+}
+
+function detail(id) {
+ console.log(url + id);
+ const html = request(url + id);
+ const $ = load(html);
+ // var jsBase = js2Proxy(true, siteType, siteKey, 'img/', {});
+ const detail = $('div.detail > .meta');
+ let vod = {
+ vod_id: id,
+ // vod_pic: jsBase + base64Encode($('div.item-root > img')[0].attribs['data-src']),
+ vod_pic: $('div.item-root > img')[0].attribs['data-src'] + '@Referer=' + url + '@User-Agent=' + UA,
+ vod_remarks: '',
+ };
+ for (const info of detail) {
+ if ($(info).hasClass('title')) {
+ vod.vod_name = info.children[0].data;
+ } else if ($(info).hasClass('year')) {
+ vod.vod_area = info.children[0].data;
+ } else if ($(info).hasClass('country')) {
+ vod.vod_area = info.children[0].data;
+ } else if ($(info).hasClass('celebrity')) {
+ vod.vod_actor = info.children[0].data;
+ }
+ }
+
+ const res = req(url + '/api/getResN?videoId=' + id.substring(id.lastIndexOf('/') + 1) + '&mtype=2', {
+ headers: {
+ 'User-Agent': UA
+ }
+ });
+ const list = JSON.parse(res.content).data.list;
+ let playlist = {};
+ for (const l of list) {
+ const flagData = JSON.parse(l.resData);
+ for (const f of flagData) {
+ const from = f.flag;
+ const urls = f.url;
+ if (!from || !urls) continue;
+ if (playlist[from]) continue;
+ playlist[from] = urls;
+ }
+ }
+ vod.vod_play_from = _.keys(playlist).join('$$$');
+ vod.vod_play_url = _.values(playlist).join('$$$');
+ return JSON.stringify({
+ list: [vod],
+ });
+}
+
+function base64Encode(text) {
+ return Crypto.enc.Base64.stringify(Crypto.enc.Utf8.parse(text));
+}
+
+function base64Decode(text) {
+ return Crypto.enc.Utf8.stringify(Crypto.enc.Base64.parse(text));
+}
+
+function proxy(params) {
+ console.log(JSON.stringify(params));
+ // {"from":"catvod","header":"{}","do":"js","url":"img/aHR0cHM6Ly9pbWcxLmlrYW5ib3QuY29tL2ltYWdlcy81L2I2LzE5OWQ1ZDhmZmQ1YmRhZDk5ZGVlNzY1MjQ3NjliYjY1LmpwZw=="}
+ let segments = params.url.split("/");
+ let what = segments[0];
+ let url = base64Decode(segments[1]);
+ if (what == 'img') {
+ var resp = req(url, {
+ buffer: 2,
+ headers: {
+ Referer: url,
+ 'User-Agent': UA,
+ },
+ });
+ console.log('@Referer=' + url + '@User-Agent=' + UA );
+ return JSON.stringify({
+ code: resp.code,
+ buffer: 2,
+ content: resp.content,
+ headers: resp.headers,
+ });
+ }
+ return JSON.stringify({
+ code: 500,
+ content: '',
+ });
+}
+
+function play(flag, id, flags) {
+ return JSON.stringify({
+ parse: 0,
+ url: id,
+ });
+}
+
+function search(wd, quick, pg) {
+ if (pg <= 0 || typeof(pg) == 'undefined') pg = 1;
+ const html = request(url + '/search?q=' + wd + '&p=' + pg);
+ const $ = load(html);
+ const items = $('div.media');
+ // var jsBase = js2Proxy(true, siteType, siteKey, 'img/', {});
+ let videos = _.map(items, (item) => {
+ const a = $(item).find('a:first')[0];
+ const img = $(item).find('img:first')[0];
+ const remarks = $($(item).find('span.label')[0]).text().trim();
+ return {
+ vod_id: a.attribs.href,
+ vod_name: img.attribs.alt,
+ // vod_pic: jsBase + base64Encode(img.attribs['data-src']),
+ vod_pic: img.attribs['data-src'] + '@Referer=' + url + '@User-Agent=' + UA,
+ vod_remarks: remarks || '',
+ };
+ });
+ const hasMore = $('div.page-more > a:contains(下一页)').length > 0;
+ const pgCount = hasMore ? parseInt(pg) + 1 : parseInt(pg);
+ return JSON.stringify({
+ page: parseInt(pg),
+ pagecount: pgCount,
+ list: videos,
+ });
+}
+
+export function __jsEvalReturn() {
+ return {
+ init: init,
+ home: home,
+ homeVod: homeVod,
+ category: category,
+ detail: detail,
+ play: play,
+ proxy: proxy,
+ search: search,
+ };
+}
diff --git a/cat/ikanbot_open.js b/cat/ikanbot_open.js
index e667921..68566f2 100644
--- a/cat/ikanbot_open.js
+++ b/cat/ikanbot_open.js
@@ -55,7 +55,22 @@ async function home(filter) {
}
async function homeVod() {
- return '{}';
+ const html = await request(url);
+ const $ = load(html);
+ const items = $('div.v-list a.item');
+ var jsBase = await js2Proxy(true, siteType, siteKey, 'img/', {});
+ let videos = _.map(items, (item) => {
+ const img = $(item).find('img:first')[0];
+ return {
+ vod_id: item.attribs.href,
+ vod_name: img.attribs.alt,
+ vod_pic: jsBase + base64Encode(img.attribs['data-src']),
+ vod_remarks: '',
+ };
+ });
+ return JSON.stringify({
+ list: videos,
+ });
}
async function category(tid, pg, filter, extend) {
@@ -86,50 +101,85 @@ async function category(tid, pg, filter, extend) {
}
async function detail(id) {
- const html = await request(url + id);
- const $ = load(html);
- var jsBase = await js2Proxy(true, siteType, siteKey, 'img/', {});
- const detail = $('div.detail > .meta');
- let vod = {
- vod_id: id,
- vod_pic: jsBase + base64Encode($('div.item-root > img')[0].attribs['data-src']),
- vod_remarks: '',
- };
- for (const info of detail) {
- if ($(info).hasClass('title')) {
- vod.vod_name = info.children[0].data;
- } else if ($(info).hasClass('year')) {
- vod.vod_area = info.children[0].data;
- } else if ($(info).hasClass('country')) {
- vod.vod_area = info.children[0].data;
- } else if ($(info).hasClass('celebrity')) {
- vod.vod_actor = info.children[0].data;
- }
- }
-
- const res = await req(url + '/api/getResN?videoId=' + id.substring(id.lastIndexOf('/') + 1) + '&mtype=2', {
- headers: {
- Referer: url,
- 'User-Agent': UA,
- },
- });
- const list = JSON.parse(res.content).data.list;
- let playlist = {};
- for (const l of list) {
- const flagData = JSON.parse(l.resData);
- for (const f of flagData) {
- const from = f.flag;
- const urls = f.url;
- if (!from || !urls) continue;
- if (playlist[from]) continue;
- playlist[from] = urls;
- }
- }
- vod.vod_play_from = _.keys(playlist).join('$$$');
- vod.vod_play_url = _.values(playlist).join('$$$');
- return JSON.stringify({
- list: [vod],
- });
+ const html = await request(url + id);
+ const $ = load(html);
+ var jsBase = await js2Proxy(true, siteType, siteKey, 'img/', {});
+ const detail = $('div.detail');
+ const remarks = $('span#line-tips').text();
+ let vod = {
+ vod_id: id,
+ vod_pic: jsBase + base64Encode($('div.item-root > img')[0].attribs['data-src']),
+ vod_remarks: '',
+ vod_content: remarks || '',
+ vod_name: $(detail).find('h2').text().trim(),
+ vod_year: $(detail).find('h3:nth-child(3)').text(),
+ vod_area: $(detail).find('h3:nth-child(4)').text(),
+ vod_actor: $(detail).find('h3:nth-child(5)').text(),
+ };
+ const res = await req(url + '/api/getResN?videoId=' + id.substring(id.lastIndexOf('/') + 1) + '&mtype=2&token=9109590b194731fde643ce27924fcf6f', {
+ headers: {
+ Referer: 'play',
+ 'User-Agent': UA,
+ },
+ });
+ const list = JSON.parse(res.content).data.list;
+ let playlist = {};
+ let arr = []
+ for (const l of list) {
+ const flagData = JSON.parse(l.resData);
+ for (const f of flagData) {
+ const from = f.flag;
+ const urls = f.url;
+ if (!from || !urls) continue;
+ if (playlist[from]) continue;
+ playlist[from] = urls;
+ }
+ }
+ for (var key in playlist) {
+ if ('kuaikan' == key) {
+ arr.push({
+ flag: '快看',
+ url: playlist[key],
+ sort: 1
+ })
+ } else if ('bfzym3u8' == key) {
+ arr.push({
+ flag: '暴风',
+ url: playlist[key],
+ sort: 2
+ })
+ } else if ('ffm3u8' == key) {
+ arr.push({
+ flag: '非凡',
+ url: playlist[key],
+ sort: 3
+ })
+ } else if ('lzm3u8' == key) {
+ arr.push({
+ flag: '量子',
+ url: playlist[key],
+ sort: 4
+ })
+ } else {
+ arr.push({
+ flag: key,
+ url: playlist[key],
+ sort: 5
+ })
+ }
+ }
+ arr.sort((a, b) => a.sort - b.sort);
+ let playFrom = [];
+ let playList = [];
+ arr.map(val => {
+ playFrom.push(val.flag);
+ playList.push(val.url);
+ })
+ vod.vod_play_from = playFrom.join("$$$");
+ vod.vod_play_url = playList.join("$$$");
+ return JSON.stringify({
+ list: [vod],
+ });
}
function base64Encode(text) {