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) {