Add files via upload

This commit is contained in:
alantang 2023-12-06 16:43:00 +08:00 committed by GitHub
parent afc997a122
commit 553233ab38
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 1730 additions and 0 deletions

149
cat/1080kk_open.js Normal file
View file

@ -0,0 +1,149 @@
import { Crypto, load, _, jinja2 } from './lib/cat.js';
let key = '108kk';
let HOST = 'https://www.1080kk.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';
async function request(reqUrl, agentSp) {
let res = await req(reqUrl, {
method: 'get',
headers: {
'User-Agent': agentSp || UA,
'Referer': HOST
},
});
return res.content;
}
// cfg = {skey: siteKey, ext: extend}
async function init(cfg) {
siteKey = cfg.skey;
siteType = cfg.stype;
}
async function home(filter) {
let classes = [{"type_id":1,"type_name":"电影"},{"type_id":2,"type_name":"追剧"},{"type_id":3,"type_name":"综艺"},{"type_id":4,"type_name":"动漫"}];
let filterObj = {
"2":[{"key":"cateId","name":"类型","value":[{"n":"全部","v":"2"},{"n":"陆剧","v":"13"},{"n":"日韩剧","v":"15"},{"n":"欧美剧","v":"16"},{"n":"港台剧","v":"14"}]},{"key":"class","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":"商战"}]},{"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"}]},{"key":"letter","name":"字母","value":[{"n":"全部","v":""},{"n":"A","v":"A"},{"n":"B","v":"B"},{"n":"C","v":"C"},{"n":"D","v":"D"},{"n":"E","v":"E"},{"n":"F","v":"F"},{"n":"G","v":"G"},{"n":"H","v":"H"},{"n":"I","v":"I"},{"n":"J","v":"J"},{"n":"K","v":"K"},{"n":"L","v":"L"},{"n":"M","v":"M"},{"n":"N","v":"N"},{"n":"O","v":"O"},{"n":"P","v":"P"},{"n":"Q","v":"Q"},{"n":"R","v":"R"},{"n":"S","v":"S"},{"n":"T","v":"T"},{"n":"U","v":"U"},{"n":"V","v":"V"},{"n":"W","v":"W"},{"n":"X","v":"X"},{"n":"Y","v":"Y"},{"n":"Z","v":"Z"}]},{"key":"by","name":"排序","value":[{"n":"时间","v":"time"},{"n":"人气","v":"hits"},{"n":"评分","v":"score"}]}],
"1":[{"key":"cateId","name":"类型","value":[{"n":"全部","v":"1"},{"n":"动作片","v":"6"},{"n":"喜剧片","v":"7"},{"n":"爱情片","v":"8"},{"n":"科幻片","v":"9"},{"n":"恐怖片","v":"10"},{"n":"剧情片","v":"11"},{"n":"战争片","v":"12"}]},{"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"}]},{"key":"letter","name":"字母","value":[{"n":"全部","v":""},{"n":"A","v":"A"},{"n":"B","v":"B"},{"n":"C","v":"C"},{"n":"D","v":"D"},{"n":"E","v":"E"},{"n":"F","v":"F"},{"n":"G","v":"G"},{"n":"H","v":"H"},{"n":"I","v":"I"},{"n":"J","v":"J"},{"n":"K","v":"K"},{"n":"L","v":"L"},{"n":"M","v":"M"},{"n":"N","v":"N"},{"n":"O","v":"O"},{"n":"P","v":"P"},{"n":"Q","v":"Q"},{"n":"R","v":"R"},{"n":"S","v":"S"},{"n":"T","v":"T"},{"n":"U","v":"U"},{"n":"V","v":"V"},{"n":"W","v":"W"},{"n":"X","v":"X"},{"n":"Y","v":"Y"},{"n":"Z","v":"Z"}]},{"key":"by","name":"排序","value":[{"n":"时间","v":"time"},{"n":"人气","v":"hits"},{"n":"评分","v":"score"}]}],
"3":[{"key":"class","name":"剧情","value":[{"n":"全部","v":""},{"n":"国综","v":"大陆综艺"},{"n":"港综","v":"港台综艺"},{"n":"韩日综","v":"日韩综艺"},{"n":"欧美综","v":"欧美综艺"}]},{"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"}]},{"key":"letter","name":"字母","value":[{"n":"全部","v":""},{"n":"A","v":"A"},{"n":"B","v":"B"},{"n":"C","v":"C"},{"n":"D","v":"D"},{"n":"E","v":"E"},{"n":"F","v":"F"},{"n":"G","v":"G"},{"n":"H","v":"H"},{"n":"I","v":"I"},{"n":"J","v":"J"},{"n":"K","v":"K"},{"n":"L","v":"L"},{"n":"M","v":"M"},{"n":"N","v":"N"},{"n":"O","v":"O"},{"n":"P","v":"P"},{"n":"Q","v":"Q"},{"n":"R","v":"R"},{"n":"S","v":"S"},{"n":"T","v":"T"},{"n":"U","v":"U"},{"n":"V","v":"V"},{"n":"W","v":"W"},{"n":"X","v":"X"},{"n":"Y","v":"Y"},{"n":"Z","v":"Z"}]},{"key":"by","name":"排序","value":[{"n":"时间","v":"time"},{"n":"人气","v":"hits"},{"n":"评分","v":"score"}]}],
"4":[{"key":"class","name":"剧情","value":[{"n":"全部","v":""},{"n":"国漫","v":"国产动漫"},{"n":"日韩动漫","v":"日韩动漫"},{"n":"欧美动漫","v":"欧美动漫"},{"n":"港漫","v":"港台动漫"},{"n":"海外动漫","v":"海外动漫"}]},{"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"}]},{"key":"letter","name":"字母","value":[{"n":"全部","v":""},{"n":"A","v":"A"},{"n":"B","v":"B"},{"n":"C","v":"C"},{"n":"D","v":"D"},{"n":"E","v":"E"},{"n":"F","v":"F"},{"n":"G","v":"G"},{"n":"H","v":"H"},{"n":"I","v":"I"},{"n":"J","v":"J"},{"n":"K","v":"K"},{"n":"L","v":"L"},{"n":"M","v":"M"},{"n":"N","v":"N"},{"n":"O","v":"O"},{"n":"P","v":"P"},{"n":"Q","v":"Q"},{"n":"R","v":"R"},{"n":"S","v":"S"},{"n":"T","v":"T"},{"n":"U","v":"U"},{"n":"V","v":"V"},{"n":"W","v":"W"},{"n":"X","v":"X"},{"n":"Y","v":"Y"},{"n":"Z","v":"Z"}]},{"key":"by","name":"排序","value":[{"n":"时间","v":"time"},{"n":"人气","v":"hits"},{"n":"评分","v":"score"}]}]
};
return JSON.stringify({
class: classes,
filters: filterObj,
});
}
async function homeVod() {}
async function category(tid, pg, filter, extend) {
if (pg <= 0) pg = 1;
const link = HOST + '/vodshow/' + (extend.CateId || tid) + '--' + (extend.by || 'time') + '-' + (extend.class || '') + '--' + (extend.letter || '') + '---' + pg + '---' + (extend.year || '') + '.html';//https://www.1080kk.com/vodshow/13--hits-%E5%8F%A4%E8%A3%85-%E5%9B%BD%E8%AF%AD-B------2022.html
const html = await request(link);
const $ = load(html);
const items = $('ul.myui-vodlist > li');
let videos = _.map(items, (item) => {
const it = $(item).find('a:first')[0];
const remarks = $($(item).find('span.pic-text text-right')[0]).text().trim();
return {
vod_id: it.attribs.href.replace(/.*?\/voddetail\/(.*).html/g, '$1'),
vod_name: it.attribs.title,
vod_pic: it.attribs['data-original'],
vod_remarks: remarks || '',
};
});
const hasMore = $('ul.myui-page > li > 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,
});
}
async function detail(id) {
var html = await request( HOST + '/voddetail/' + id + '.html');
var $ = load(html);
var vod = {
vod_id: id,
vod_name: $('h1:first').text().trim(),
vod_type: $('.stui-content__detail p:first a').text(),
vod_actor: $('.stui-content__detail p:nth-child(3)').text().replace('主演:',''),
vod_pic: $('.stui-content__thumb img:first').attr('data-original'),
vod_remarks : $('.stui-content__detail p:nth-child(5)').text() || '',
vod_content: $('span.detail-content').text().trim(),
};
var playMap = {};
var tabs = $('ul.nav-tabs > li > a[data-toggle*=tab]');
var playlists = $('ul.myui-content__list');
_.each(tabs, (tab, i) => {
var from = tab.children[0].data;
var list = playlists[i];
list = $(list).find('a');
_.each(list, (it) => {
var title = it.children[0].data;
var playUrl = it.attribs.href.replace(/\/vodplay\/(.*).html/g, '$1');
if (title.length == 0) title = it.children[0].data.trim();
if (!playMap.hasOwnProperty(from)) {
playMap[from] = [];
}
playMap[from].push( title + '$' + playUrl);
});
});
vod.vod_play_from = _.keys(playMap).join('$$$');
var urls = _.values(playMap);
var vod_play_url = _.map(urls, (urlist) => {
return urlist.join('#');
});
vod.vod_play_url = vod_play_url.join('$$$');
return JSON.stringify({
list: [vod],
});
}
async function play(flag, id, flags) {
const link = HOST + '/vodplay/' + id + '.html';
const html = await request(link);
const $ = load(html);
const js = JSON.parse($('script:contains(player_)').html().replace('var player_aaaa=',''));
const playurl = js.url;
const playUrl = unescape(playurl);
return JSON.stringify({
parse: 0,
url: playUrl,
});
}
async function search(wd, quick) {
let data = JSON.parse(await request(HOST + '/index.php/ajax/suggest?mid=1&wd=' + wd)).list;
let videos = [];
for (const vod of data) {
videos.push({
vod_id: vod.id,
vod_name: vod.name,
vod_pic: vod.pic,
vod_remarks: '',
});
}
return JSON.stringify({
list: videos,
});
}
export function __jsEvalReturn() {
return {
init: init,
home: home,
homeVod: homeVod,
category: category,
detail: detail,
play: play,
search: search,
};
}

1
cat/18av_open.js Normal file

File diff suppressed because one or more lines are too long

261
cat/230ts_book_open.js Normal file
View file

@ -0,0 +1,261 @@
// 网站搜索异常
import { load, _ } from './lib/cat.js';
let key = '爱上你听书网';
let HOST = 'https://wap.230ts.net';
let siteKey = '';
let siteType = 0;
const MOBILE_UA = 'Mozilla/5.0 (Linux; Android 11; M2007J3SC Build/RKQ1.200826.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045714 Mobile Safari/537.36';
async function request(reqUrl, agentSp) {
let res = await req(reqUrl, {
method: 'get',
headers: {
'User-Agent': agentSp || MOBILE_UA,
'Referer': HOST
},
});
return res.content;
}
// cfg = {skey: siteKey, ext: extend}
async function init(cfg) {
siteKey = cfg.skey;
siteType = cfg.stype;
}
async function home(filter) {
const html = await request(HOST + '/sort/');
const $ = load(html);
let filterObj = {};
const class_parse = $('dl.pd-class:first > dd > a[href*=sort]');
let classes = [];
classes = _.map(class_parse, (cls) => {
let typeId = cls.attribs['href'];
typeId = typeId.replace(/.*?\/sort\/(.*).html/g, '$1');
return {
type_id: typeId,
type_name: cls.children[0].data,
};
});
const sortName = ['玄幻有声', '灵异有声', '综艺娱乐', '长篇评书', '都市有声', '军事有声', '职场有声', '其他有声'];
classes = _.sortBy(classes, (c) => {
const index = sortName.indexOf(c.type_name);
return index === -1 ? sortName.length : index;
});
return JSON.stringify({
class: classes,
filters: filterObj,
});
}
async function homeVod() {
const link = HOST + '/top/lastupdate/1.html';
const html = await request(link);
const $ = load(html);
const items = $('ul.list-ul > li');
let videos = _.map(items, (item) => {
const it = $(item).find('a:first')[0];
const img = $(item).find('img:first')[0];
const remarks = $($(item).find('p.module-slide-author')[0]).text().trim();
return {
vod_id: it.attribs.href.replace(/.*?\/tingshu\/(.*)/g, '$1'),
vod_name: it.attribs.title.replace('有声小说',''),
vod_pic: HOST + img.attribs['data-original'],
vod_remarks: remarks || '',
};
});
return JSON.stringify({
list: videos,
});
}
async function category(tid, pg, filter, extend) {
if (pg <= 0) pg = 1;
const link = HOST + '/sort/' + tid +'/' + (`${pg}`) + '.html';
const html = await request(link);
const $ = load(html);
const items = $('ul.book-ol > li');
let videos = _.map(items, (item) => {
const it = $(item).find('a:first')[0];
const img = $(item).find('img:first')[0];
const remarks = $($(item).find('div.book-meta')[0]).text().trim();
return {
book_id: it.attribs.href.replace(/.*?\/tingshu\/(.*)/g, '$1'),
book_name: it.attribs.title.replace('有声小说',''),
book_pic: HOST + img.attribs['data-original'],
book_remarks: remarks.replace('佚名(著)','').replace('佚名(播)','').replace('未知(著)','').replace('未知(播)','') || '',
};
});
const hasMore = $('div.paging > 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,
});
}
async function detail(id) {
const html = await request(HOST + '/tingshu/' + id);
const $ = load(html);
const detail = $('div.book-cell:first > div');
let vod = {
book_id: id,
type_name: $('h1:first').text().trim().replace('有声小说',''),
// vod_pic: HOST + $('div.myui-content__thumb img:first').attr('data-original'),
// vod_content: $('div.ellipsis').text().trim(),
book_year: '',
book_area: '',
book_remarks: '',
book_actor: '',
book_director: '',
book_content: '',
};
// for (const info of detail) {
// const i = $(info).text().trim();
// if (i.startsWith('类型:')) {
// vod.vod_type = _.map($(info).find('a'), (a) => {
// return a.children[0].data;
// }).join('/');
// } else if (i.startsWith('作者:')) {
// vod.vod_director = _.map($(info).find('a'), (a) => {
// return a.children[0].data;
// }).join('/');
// } else if (i.startsWith('演播:')) {
// vod.vod_actor = _.map($(info).find('a'), (a) => {
// return a.children[0].data;
// }).join('/');
// } else if (i.startsWith('连载中')) {
// vod.vod_remarks = i.substring(3);
// }
// }
const playlist = _.map($('#playlist > ul > li > a'), (it) => {
return it.children[0].data + '$' + it.attribs.href.replace(/\/mp3\/(.*).html/g, '$1');
}).join("#");
vod.volumes = '道长在线';
vod.urls = playlist;
// vod.vod_play_from = '道长在线';
// vod.vod_play_url = playlist.join('#');
return JSON.stringify({
list: [vod],
});
}
async function play(flag, id, flags) {
const link = HOST + '/mp3/' + id + '.html';
const html = await request(link);
const $ = load(html);
const iframe = $('body iframe[src*=player]');
const iframeHtml = (
await req(HOST + iframe[0].attribs.src, {
headers: {
'Referer': link,
'User-Agent': MOBILE_UA,
},
})
).content;
const playUrl = iframeHtml.match(/mp3:'(.*?)'/)[1];
if (playUrl.indexOf('m4a') >= 0 || playUrl.indexOf('mp3') >= 0 ) {
return JSON.stringify({
parse: 0,
url: playUrl,
});
} else {
try {
const iframeHtml = (
await req(HOST + iframe[0].attribs.src, {
headers: {
'Referer': link,
'User-Agent': MOBILE_UA,
},
})
).content;
const playUrl = playUrl + '.m4a' + iframeHtml.match(/(\?.*?)'/)[1];
if (playUrl.indexOf('http') >= 0) {
return JSON.stringify({
parse: 0,
url: playUrl,
});
} else {
const iframeHtml = (
await req(HOST + iframe[0].attribs.src, {
headers: {
'Referer': link,
'User-Agent': MOBILE_UA,
},
})
).content;
const playUrl2 = iframeHtml.match(/url[\s\S]*?(http.*?)'/)[1];
if (playUrl2.indexOf('\?') >= 0) {
return JSON.stringify({
parse: 0,
url: playUrl2,
});
} else {
const playUrl3 = playUrl2 + playUrl
return JSON.stringify({
parse: 0,
url: playUrl3,
});
}
}
} catch (e) {}
if (playUrl.indexOf('http') >= 0) {
const playUrl = playUrl + '.m4a';
return JSON.stringify({
parse: 0,
url: playUrl,
});
} else {
const iframeHtml = (
await req(HOST + iframe[0].attribs.src, {
headers: {
'Referer': link,
'User-Agent': MOBILE_UA,
},
})
).content;
const playUrl4 = iframeHtml.match(/url[\s\S]*?(http.*?)'/)[1];
return JSON.stringify({
parse: 0,
url: playUrl4 + '.m4a',
});
}
}
}
async function search(wd, quick) {
const link = HOST + '/search.html?searchtype=name&searchword=' + wd +'&page=1';
const html = await request(link);
const $ = load(html);
const items = $('ul.book-ol > li');
let videos = _.map(items, (item) => {
const it = $(item).find('a:first')[0];
const img = $(item).find('img:first')[0];
const remarks = $($(item).find('div.book-meta')[0]).text().trim();
return {
book_id: it.attribs.href.replace(/.*?\/tingshu\/(.*)/g, '$1'),
book_name: it.attribs.title.replace('有声小说',''),
book_pic: img.attribs['data-original'],
book_remarks: remarks.replace('佚名(著)','').replace('佚名(播)','').replace('未知(著)','').replace('未知(播)','') || '',
};
});
return JSON.stringify({
list: videos,
});
}
export function __jsEvalReturn() {
return {
init: init,
home: home,
homeVod: homeVod,
category: category,
detail: detail,
play: play,
search: search,
};
}

253
cat/230ts_open.js Normal file
View file

@ -0,0 +1,253 @@
// 网站搜索异常
import { load, _ } from './lib/cat.js';
let key = '爱上你听书网';
let HOST = 'https://wap.230ts.net';
let siteKey = '';
let siteType = 0;
const MOBILE_UA = 'Mozilla/5.0 (Linux; Android 11; M2007J3SC Build/RKQ1.200826.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045714 Mobile Safari/537.36';
async function request(reqUrl, agentSp) {
let res = await req(reqUrl, {
method: 'get',
headers: {
'User-Agent': agentSp || MOBILE_UA,
'Referer': HOST
},
});
return res.content;
}
// cfg = {skey: siteKey, ext: extend}
async function init(cfg) {
siteKey = cfg.skey;
siteType = cfg.stype;
}
async function home(filter) {
const html = await request(HOST + '/sort/');
const $ = load(html);
let filterObj = {};
const class_parse = $('dl.pd-class:first > dd > a[href*=sort]');
let classes = [];
classes = _.map(class_parse, (cls) => {
let typeId = cls.attribs['href'];
typeId = typeId.replace(/.*?\/sort\/(.*).html/g, '$1');
return {
type_id: typeId,
type_name: cls.children[0].data,
};
});
const sortName = ['玄幻有声', '灵异有声', '综艺娱乐', '长篇评书', '都市有声', '军事有声', '职场有声', '其他有声'];
classes = _.sortBy(classes, (c) => {
const index = sortName.indexOf(c.type_name);
return index === -1 ? sortName.length : index;
});
return JSON.stringify({
class: classes,
filters: filterObj,
});
}
async function homeVod() {
const link = HOST + '/top/lastupdate/1.html';
const html = await request(link);
const $ = load(html);
const items = $('ul.list-ul > li');
let videos = _.map(items, (item) => {
const it = $(item).find('a:first')[0];
const img = $(item).find('img:first')[0];
const remarks = $($(item).find('p.module-slide-author')[0]).text().trim();
return {
vod_id: it.attribs.href.replace(/.*?\/tingshu\/(.*)/g, '$1'),
vod_name: it.attribs.title.replace('有声小说',''),
vod_pic: HOST + img.attribs['data-original'],
vod_remarks: remarks || '',
};
});
return JSON.stringify({
list: videos,
});
}
async function category(tid, pg, filter, extend) {
if (pg <= 0) pg = 1;
const link = HOST + '/sort/' + tid +'/' + (`${pg}`) + '.html';
const html = await request(link);
const $ = load(html);
const items = $('ul.book-ol > li');
let videos = _.map(items, (item) => {
const it = $(item).find('a:first')[0];
const img = $(item).find('img:first')[0];
const remarks = $($(item).find('div.book-meta')[0]).text().trim();
return {
vod_id: it.attribs.href.replace(/.*?\/tingshu\/(.*)/g, '$1'),
vod_name: it.attribs.title.replace('有声小说',''),
vod_pic: HOST + img.attribs['data-original'],
vod_remarks: remarks.replace('佚名(著)','').replace('佚名(播)','').replace('未知(著)','').replace('未知(播)','') || '',
};
});
const hasMore = $('div.paging > 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,
});
}
async function detail(id) {
const html = await request(HOST + '/tingshu/' + id);
const $ = load(html);
const detail = $('div.book-cell:first > div');
let vod = {
vod_id: id,
vod_name: $('h1:first').text().trim().replace('有声小说',''),
vod_pic: HOST + $('div.myui-content__thumb img:first').attr('data-original'),
vod_content: $('div.ellipsis').text().trim(),
};
for (const info of detail) {
const i = $(info).text().trim();
if (i.startsWith('类型:')) {
vod.vod_type = _.map($(info).find('a'), (a) => {
return a.children[0].data;
}).join('/');
} else if (i.startsWith('作者:')) {
vod.vod_director = _.map($(info).find('a'), (a) => {
return a.children[0].data;
}).join('/');
} else if (i.startsWith('演播:')) {
vod.vod_actor = _.map($(info).find('a'), (a) => {
return a.children[0].data;
}).join('/');
} else if (i.startsWith('连载中')) {
vod.vod_remarks = i.substring(3);
}
}
const playlist = _.map($('#playlist > ul > li > a'), (it) => {
return it.children[0].data + '$' + it.attribs.href.replace(/\/mp3\/(.*).html/g, '$1');
});
vod.vod_play_from = '道长在线';
vod.vod_play_url = playlist.join('#');
return JSON.stringify({
list: [vod],
});
}
async function play(flag, id, flags) {
const link = HOST + '/mp3/' + id + '.html';
const html = await request(link);
const $ = load(html);
const iframe = $('body iframe[src*=player]');
const iframeHtml = (
await req(HOST + iframe[0].attribs.src, {
headers: {
'Referer': link,
'User-Agent': MOBILE_UA,
},
})
).content;
const playUrl = iframeHtml.match(/mp3:'(.*?)'/)[1];
if (playUrl.indexOf('m4a') >= 0 || playUrl.indexOf('mp3') >= 0 ) {
return JSON.stringify({
parse: 0,
url: playUrl,
});
} else {
try {
const iframeHtml = (
await req(HOST + iframe[0].attribs.src, {
headers: {
'Referer': link,
'User-Agent': MOBILE_UA,
},
})
).content;
const playUrl = playUrl + '.m4a' + iframeHtml.match(/(\?.*?)'/)[1];
if (playUrl.indexOf('http') >= 0) {
return JSON.stringify({
parse: 0,
url: playUrl,
});
} else {
const iframeHtml = (
await req(HOST + iframe[0].attribs.src, {
headers: {
'Referer': link,
'User-Agent': MOBILE_UA,
},
})
).content;
const playUrl2 = iframeHtml.match(/url[\s\S]*?(http.*?)'/)[1];
if (playUrl2.indexOf('\?') >= 0) {
return JSON.stringify({
parse: 0,
url: playUrl2,
});
} else {
const playUrl3 = playUrl2 + playUrl
return JSON.stringify({
parse: 0,
url: playUrl3,
});
}
}
} catch (e) {}
if (playUrl.indexOf('http') >= 0) {
const playUrl = playUrl + '.m4a';
return JSON.stringify({
parse: 0,
url: playUrl,
});
} else {
const iframeHtml = (
await req(HOST + iframe[0].attribs.src, {
headers: {
'Referer': link,
'User-Agent': MOBILE_UA,
},
})
).content;
const playUrl4 = iframeHtml.match(/url[\s\S]*?(http.*?)'/)[1];
return JSON.stringify({
parse: 0,
url: playUrl4 + '.m4a',
});
}
}
}
async function search(wd, quick) {
const link = HOST + '/search.html?searchtype=name&searchword=' + wd +'&page=1';
const html = await request(link);
const $ = load(html);
const items = $('ul.book-ol > li');
let videos = _.map(items, (item) => {
const it = $(item).find('a:first')[0];
const img = $(item).find('img:first')[0];
const remarks = $($(item).find('div.book-meta')[0]).text().trim();
return {
vod_id: it.attribs.href.replace(/.*?\/tingshu\/(.*)/g, '$1'),
vod_name: it.attribs.title.replace('有声小说',''),
vod_pic: img.attribs['data-original'],
vod_remarks: remarks.replace('佚名(著)','').replace('佚名(播)','').replace('未知(著)','').replace('未知(播)','') || '',
};
});
return JSON.stringify({
list: videos,
});
}
export function __jsEvalReturn() {
return {
init: init,
home: home,
homeVod: homeVod,
category: category,
detail: detail,
play: play,
search: search,
};
}

1
cat/4kys_open.js Normal file

File diff suppressed because one or more lines are too long

1
cat/52ju_open.js Normal file

File diff suppressed because one or more lines are too long

1
cat/555dy_open.js Normal file

File diff suppressed because one or more lines are too long

1
cat/58dm_open.js Normal file

File diff suppressed because one or more lines are too long

1
cat/abu_open.js Normal file

File diff suppressed because one or more lines are too long

1
cat/adm_open.js Normal file

File diff suppressed because one or more lines are too long

275
cat/alist_open.js Normal file
View file

@ -0,0 +1,275 @@
import { _ } from './lib/cat.js';
import { findBestLCS } from './lib/similarity.js';
const http = async function (url, options = {}) {
if (options.method == 'POST' && options.data) {
options.body = JSON.stringify(options.data);
options.headers = Object.assign({ 'content-type': 'application/json' }, options.headers);
}
const res = await req(url, options);
res.json = () => (res.content ? JSON.parse(res.content) : null);
res.text = () => res.content;
return res;
};
['get', 'post'].forEach((method) => {
http[method] = function (url, options = {}) {
return http(url, Object.assign(options, { method: method.toUpperCase() }));
};
});
const __drives = {};
const __subtitle_cache = {};
async function get_drives_path(tid) {
const index = tid.indexOf('/', 1);
const name = tid.substring(1, index);
const path = tid.substring(index);
return { drives: await get_drives(name), path };
}
async function get_drives(name) {
const { settings, api, server } = __drives[name];
if (settings.v3 == null) {
//获取 设置
settings.v3 = false;
const data = (await http.get(server + '/api/public/settings')).json().data;
if (_.isArray(data)) {
settings.title = data.find((x) => x.key == 'title')?.value;
settings.v3 = false;
settings.version = data.find((x) => x.key == 'version')?.value;
settings.enableSearch = data.find((x) => x.key == 'enable search')?.value == 'true';
} else {
settings.title = data.title;
settings.v3 = true;
settings.version = data.version;
settings.enableSearch = false; //v3 没有找到 搜索配置
}
//不同版本 接口不一样
api.path = settings.v3 ? '/api/fs/list' : '/api/public/path';
api.file = settings.v3 ? '/api/fs/get' : '/api/public/path';
api.search = settings.v3 ? '/api/public/search' : '/api/public/search';
api.other = settings.v3 ? '/api/fs/other' : null;
}
return __drives[name];
}
let siteKey = '';
let siteType = 0;
function init(cfg) {
siteKey = cfg.skey;
siteType = cfg.stype;
cfg.ext.forEach(
(item) =>
(__drives[item.name] = {
name: item.name,
server: item.server.endsWith('/') ? item.server.substring(0, item.server.length - 1) : item.server,
startPage: item.startPage || '/', //首页
showAll: item.showAll === true, //默认只显示 视频和文件夹,如果想显示全部 showAll 设置true
params: item.params || {},
_path_param: item.params
? _.sortBy(Object.keys(item.params), function (x) {
return -x.length;
})
: [],
settings: {},
api: {},
getParams(path) {
const key = this._path_param.find((x) => path.startsWith(x));
return Object.assign({}, this.params[key], { path });
},
async getPath(path) {
const res = (await http.post(this.server + this.api.path, { data: this.getParams(path) })).json();
return this.settings.v3 ? res.data.content : res.data.files;
},
async getFile(path) {
const res = (await http.post(this.server + this.api.file, { data: this.getParams(path) })).json();
const data = this.settings.v3 ? res.data : res.data.files[0];
if (!this.settings.v3) data.raw_url = data.url; //v2 的url和v3不一样
return data;
},
async getOther(method, path) {
const data = this.getParams(path);
data.method = method;
const res = (await http.post(this.server + this.api.other, { data: data })).json();
return res;
},
isFolder(data) {
return data.type == 1;
},
isVideo(data) {
//判断是否是 视频文件
return this.settings.v3 ? data.type == 2 : data.type == 3;
},
isSubtitle(data) {
if (data.type == 1) return false;
const ext = ['.srt', '.ass', '.scc', '.stl', '.ttml'];
return ext.some((x) => data.name.endsWith(x));
},
getType(data) {
const isVideo = this.isVideo(data);
return this.isFolder(data) ? 0 : isVideo ? 10 : 1;
},
getPic(data) {
let pic = this.settings.v3 ? data.thumb : data.thumbnail;
return pic || (this.isFolder(data) ? 'http://img1.3png.com/281e284a670865a71d91515866552b5f172b.png' : '');
},
getSize(data) {
let sz = data.size || 0;
if (sz <= 0) return '';
let filesize = '';
if (sz > 1024 * 1024 * 1024 * 1024.0) {
sz /= 1024 * 1024 * 1024 * 1024.0;
filesize = 'TB';
} else if (sz > 1024 * 1024 * 1024.0) {
sz /= 1024 * 1024 * 1024.0;
filesize = 'GB';
} else if (sz > 1024 * 1024.0) {
sz /= 1024 * 1024.0;
filesize = 'MB';
} else {
sz /= 1024.0;
filesize = 'KB';
}
return sz.toFixed(2) + filesize;
},
getRemark(data) {
return '';
},
})
);
}
async function dir(dir, pg) {
for (const k in __subtitle_cache) {
delete __subtitle_cache[k];
}
pg = pg || 1;
if (pg == 0) pg == 1;
if (dir === '/' || dir === '') {
const result = _.map(__drives, function (d) {
return { name: d.name, path: '/' + d.name + d.startPage, type: 0, thumb: '' };
});
return JSON.stringify({
parent: '',
page: pg,
pagecount: pg,
list: result,
});
}
let { drives, path } = await get_drives_path(dir);
const id = dir.endsWith('/') ? dir : dir + '/';
const list = await drives.getPath(path);
let subtList = [];
let videos = [];
let allList = [];
list.forEach((item) => {
if (drives.isSubtitle(item)) subtList.push(item.name);
const isVideo = drives.isVideo(item);
if (!drives.showAll && !drives.isFolder(item) && !isVideo) return;
const file = {
name: item.name.replaceAll('$', '_').replaceAll('#', '_'),
path: id + item.name + (drives.isFolder(item) ? '/' : ''),
thumb: drives.getPic(item),
type: drives.getType(item),
size: drives.getSize(item),
remark: drives.getRemark(item),
};
if (drives.isVideo(item)) videos.push(file);
allList.push(file);
});
if (subtList.length > 0) {
videos.forEach((item) => {
var sbust = findBestLCS(item.name, subtList);
if (sbust.bestMatch) __subtitle_cache[item.path] = [id + sbust.bestMatch.target];
});
}
return JSON.stringify({
parent: id,
page: pg,
pagecount: pg,
list: allList,
});
}
async function file(file) {
let { drives, path } = await get_drives_path(file);
const item = await drives.getFile(path);
const subs = [];
if (__subtitle_cache[file]) {
for (const sub of __subtitle_cache[file]) {
try {
let subP = await get_drives_path(sub);
const subItem = await drives.getFile(subP.path);
subs.push(subItem.raw_url);
} catch (error) {}
}
}
if (item.provider === 'AliyundriveShare2Open' && drives.api.other) {
const urls = ['原画', item.raw_url];
try {
const res = await drives.getOther('video_preview', path);
for (const live of res.data.video_preview_play_info.live_transcoding_task_list) {
if (live.status === 'finished') {
urls.push(live.template_id);
urls.push(live.url);
}
}
} catch (error) {}
const result = {
name: item.name,
url: urls,
size: drives.getSize(item),
remark: drives.getRemark(item),
header: {},
extra: {
subt: subs,
},
};
return JSON.stringify(result);
} else if (item.provider === '123Pan') {
let url = item.raw_url;
try {
url = (await http.get(url)).json().data.redirect_url;
} catch (error) {}
const result = {
name: item.name,
url: url,
size: drives.getSize(item),
remark: drives.getRemark(item),
header: {},
extra: {
subt: subs,
},
};
return JSON.stringify(result);
} else {
const result = {
name: item.name,
url: item.raw_url,
size: drives.getSize(item),
remark: drives.getRemark(item),
header: {},
extra: {
subt: subs,
},
};
return JSON.stringify(result);
}
}
function search(wd) {
return JSON.stringify({
list: [],
});
}
export function __jsEvalReturn() {
return {
init: init,
dir: dir,
file: file,
search: search,
};
}

157
cat/anfun_open.js Normal file
View file

@ -0,0 +1,157 @@
import { Crypto, load, _, jinja2 } from './lib/cat.js';
let key = 'anfun';
let HOST = 'https://www.anfuns.cc';
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';
async function request(reqUrl, agentSp) {
let res = await req(reqUrl, {
method: 'get',
headers: {
'User-Agent': agentSp || UA,
'Referer': HOST
},
});
return res.content;
}
// cfg = {skey: siteKey, ext: extend}
async function init(cfg) {
siteKey = cfg.skey;
siteType = cfg.stype;
}
async function home(filter) {
let classes = [{"type_id":1,"type_name":"新旧番剧"},{"type_id":2,"type_name":"蓝光无修"},{"type_id":3,"type_name":"动漫剧场"},{"type_id":4,"type_name":"欧美动漫"}];
let filterObj = {
"1":[{"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":"2007","v":"2007"},{"n":"2006","v":"2006"},{"n":"2005","v":"2005"},{"n":"2004","v":"2004"},{"n":"2003","v":"2003"},{"n":"2002","v":"2002"},{"n":"2001","v":"2001"},{"n":"2000","v":"2000"}]},{"key":"by","name":"排序","value":[{"n":"最新","v":"/by/time"},{"n":"最热","v":"/by/hits"},{"n":"评分","v":"/by/score"}]}],
"2":[{"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":"2007","v":"2007"},{"n":"2006","v":"2006"},{"n":"2005","v":"2005"},{"n":"2004","v":"2004"},{"n":"2003","v":"2003"},{"n":"2002","v":"2002"},{"n":"2001","v":"2001"},{"n":"2000","v":"2000"}]},{"key":"by","name":"排序","value":[{"n":"最新","v":"/by/time"},{"n":"最热","v":"/by/hits"},{"n":"评分","v":"/by/score"}]}],
"3":[{"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":"2007","v":"2007"},{"n":"2006","v":"2006"},{"n":"2005","v":"2005"},{"n":"2004","v":"2004"},{"n":"2003","v":"2003"},{"n":"2002","v":"2002"},{"n":"2001","v":"2001"},{"n":"2000","v":"2000"}]},{"key":"by","name":"排序","value":[{"n":"最新","v":"/by/time"},{"n":"最热","v":"/by/hits"},{"n":"评分","v":"/by/score"}]}],
"4":[{"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":"2007","v":"2007"},{"n":"2006","v":"2006"},{"n":"2005","v":"2005"},{"n":"2004","v":"2004"},{"n":"2003","v":"2003"},{"n":"2002","v":"2002"},{"n":"2001","v":"2001"},{"n":"2000","v":"2000"}]},{"key":"by","name":"排序","value":[{"n":"最新","v":"/by/time"},{"n":"最热","v":"/by/hits"},{"n":"评分","v":"/by/score"}]}]
};
return JSON.stringify({
class: classes,
filters: filterObj,
});
}
async function homeVod() {}
async function category(tid, pg, filter, extend) {
if (pg <= 0) pg = 1;
const link = HOST + '/show/' + tid + '-' + (extend.class || '') + '--' + (extend.year || '') + (extend.by || '/by/time') + '/page/' + pg + '.html';//https://www.anfuns.cc/show/1---2023/by/hits/page/2.html
const html = await request(link);
const $ = load(html);
const items = $('ul.hl-vod-list > li');
let videos = _.map(items, (item) => {
const it = $(item).find('a:first')[0];
const remarks = $($(item).find('span.hl-lc-1')[0]).text().trim();
return {
vod_id: it.attribs.href.replace(/.*?\/anime\/(.*).html/g, '$1'),
vod_name: it.attribs.title,
vod_pic: it.attribs['data-original'],
vod_remarks: remarks || '',
};
});
const hasMore = $('ul.hl-page-wrap > li > a > span.hl-hidden-xs: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,
});
}
async function detail(id) {
var html = await request( HOST + '/anime/' + id + '.html');
var $ = load(html);
var vod = {
vod_id: id,
vod_name: $('h1:first').text().trim(),
vod_type: $('.stui-content__detail p:first a').text(),
vod_actor: $('.stui-content__detail p:nth-child(3)').text().replace('主演:',''),
vod_pic: $('.stui-content__thumb img:first').attr('data-original'),
vod_remarks : $('.stui-content__detail p:nth-child(5)').text() || '',
vod_content: $('span.detail-content').text().trim(),
};
var playMap = {};
var tabs = $('ul.hl-from-list > li > span');
var playlists = $('ul.hl-plays-list');
_.each(tabs, (tab, i) => {
var from = tab.children[0].data;
var list = playlists[i];
list = $(list).find('a');
_.each(list, (it) => {
var title = it.children[0].data;
var playUrl = it.attribs.href.replace(/\/play\/(.*).html/g, '$1');
if (!playMap.hasOwnProperty(from)) {
playMap[from] = [];
}
playMap[from].push( title + '$' + playUrl);
});
});
vod.vod_play_from = _.keys(playMap).join('$$$');
var urls = _.values(playMap);
var vod_play_url = _.map(urls, (urlist) => {
return urlist.join('#');
});
vod.vod_play_url = vod_play_url.join('$$$');
return JSON.stringify({
list: [vod],
});
}
async function play(flag, id, flags) {
const link = HOST + '/play/' + id + '.html';
const html = await request(link);
const $ = load(html);
const js = JSON.parse($('script:contains(player_)').html().replace('var player_aaaa=',''));
const playurl = js.url;
const playUrl = unescape(base64Decode(playurl));
return JSON.stringify({
parse: 0,
url: playUrl,
});
}
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));
}
async function search(wd, quick) {
let data = JSON.parse(await request(HOST + '/index.php/ajax/suggest?mid=1&wd=' + wd)).list;
let videos = [];
for (const vod of data) {
videos.push({
vod_id: vod.id,
vod_name: vod.name,
vod_pic: vod.pic,
vod_remarks: '',
});
}
return JSON.stringify({
list: videos,
});
}
export function __jsEvalReturn() {
return {
init: init,
home: home,
homeVod: homeVod,
category: category,
detail: detail,
play: play,
search: search,
};
}

8
cat/app.js Normal file
View file

@ -0,0 +1,8 @@
function __jsEvalReturn() {
return {
isVideoFormat: function (url) {
return !0;
},
};
}
export { __jsEvalReturn };

1
cat/apptov5_open.js Normal file

File diff suppressed because one or more lines are too long

1
cat/appysv2.js Normal file

File diff suppressed because one or more lines are too long

618
cat/bili_open.js Normal file
View file

@ -0,0 +1,618 @@
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 (cfg.ext.hasOwnProperty('categories')) extend = cfg.ext.categories;
if (cfg.ext.hasOwnProperty('cookie')) cookie = cfg.ext.cookie;
if (cookie.startsWith('http')) cookie = await request(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('#');
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 c = {
type_name: kk,
type_id: kk,
land: 1,
ratio: 1.33,
};
newarr.push(c);
d[kk] = jsonData;
}
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,
};
if (filter) {
jSONObject.filters = extendObj.filter;
}
return JSON.stringify(jSONObject);
} catch (e) {
return '';
}
}
async function homeVod() {
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 playUrl = j + '$' + 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("$$$");
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, '&amp;');
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 `<AdaptationSet lang="chi">
<ContentComponent contentType="${mediaType}"/>
<Representation id="${qnid}" bandwidth="${media_bandwidth}" codecs="${media_codecs}" mimeType="${media_mimeType}" ${media_type_params} startWithSAP="${media_startWithSAP}">
<BaseURL>${media_BaseURL}</BaseURL>
<SegmentBase indexRange="${media_SegmentBase_indexRange}">
<Initialization range="${media_SegmentBase_Initialization}"/>
</SegmentBase>
</Representation>
</AdaptationSet>`;
} catch (e) {
// Handle exceptions here
}
}
function getDash(ja, videoList, audioList) {
const duration = ja.data.dash.duration;
const minBufferTime = ja.data.dash.minBufferTime;
return `<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:mpeg:dash:schema:mpd:2011" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" type="static" mediaPresentationDuration="PT${duration}S" minBufferTime="PT${minBufferTime}S" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011">
<Period duration="PT${duration}S" start="PT0S">
${videoList}
${audioList}
</Period>
</MPD>`;
}
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}`;
}
}
export function __jsEvalReturn() {
return {
init: init,
home: home,
homeVod: homeVod,
category: category,
detail: detail,
play: play,
proxy: proxy,
search: search,
};
}