Sync all projects

This commit is contained in:
github-actions[bot]
2026-07-20 10:16:14 +00:00
parent a206ad21a8
commit e187f6e5af
21 changed files with 17336 additions and 9929 deletions
+11 -37
View File
@@ -5,7 +5,7 @@
"sites": [
{
"key": "豆瓣",
"name": "豆瓣|首页",
"name": "豆瓣|首页温馨提示现在只用OK跟蜂蜜壳子",
"type": 3,
"api": "csp_Douban",
"searchable": 0
@@ -36,6 +36,15 @@
"api": "csp_YGP",
"searchable": 0
},
{
"key": "兄弟影视js",
"name": "兄弟影视|秒播",
"api": "./js/兄弟影视.js",
"searchable": 1,
"quickSearch": 1,
"filterable": 1,
"type": 3
},
{
"key": "马猴影视",
"name": "马猴|秒播",
@@ -100,19 +109,7 @@
"dataIv": "1234567887654321"
}
},
{
"key": "小帅",
"name": "小帅|秒播",
"type": 3,
"api": "csp_AppGet",
"searchable": 1,
"changeable": 1,
"ext": {
"url": "https://ys.xiaos12.cn",
"dataKey": "chfgjfrhhf628vw1",
"dataIv": "chfgjfrhhf628vw1"
}
},
{
"key": "4k",
"name": "4k视频|秒播",
@@ -598,20 +595,6 @@
"dataIv": "bM7iC9eA3oZ1nB7z"
}
},
{
"key": "四叶草",
"name": "四叶草|APP",
"type": 3,
"api": "csp_AppQi",
"searchable": 1,
"changeable": 1,
"ext": {
"site": "https://yzysap.oss-cn-hangzhou.aliyuncs.com/kkk.txt",
"dataKey": "8eeObuwrmS3lRDEs",
"dataIv": "8eeObuwrmS3lRDEs",
"ua": "okhttp/3.10.0"
}
},
{
"key": "热播影视",
"name": "热播|APP",
@@ -659,15 +642,6 @@
"ua": "okhttp/3.10.0"
}
},
{
"key": "洽洽影视",
"name": "️瓜子|影视",
"type": 3,
"api": "./py/瓜子.py",
"searchable": 1,
"quickSearch": 1,
"filterable": 1
},
{
"key": "荐片",
"name": "荐片|磁力",
+342
View File
@@ -0,0 +1,342 @@
import { Crypto, load, _ } from 'assets://js/lib/cat.js';
let siteUrl = 'https://www.brovod.com';
let siteKey = '';
let siteType = 0;
let headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36',
'Referer': 'https://www.brovod.com/'
};
async function request(reqUrl, postData, get) {
let res = await req(reqUrl, {
method: get ? 'get' : 'post',
headers: headers,
data: postData || {},
postType: get ? '' : 'form',
});
return res.content;
}
async function init(cfg) {
siteKey = cfg.skey;
siteType = cfg.stype;
}
async function home(filter) {
let classes = [
{ type_id: 'Movies', type_name: '电影' },
{ type_id: 'TV', type_name: '剧集' },
{ type_id: 'Shows', type_name: '综艺' },
{ type_id: 'Anime', type_name: '动漫' },
{ type_id: 'Snaps', type_name: '短剧' },
{ type_id: 'Documentaries', type_name: '纪录片' }
];
let filterObj = genFilterObj();
return JSON.stringify({
class: classes,
filters: filterObj
});
}
function getVideos($) {
let videos = [];
$('div.public-list-box').each((i, n) => {
let a = $(n).find('a.public-list-exp');
let img = $(n).find('img.lazy');
if (a.length > 0 && img.length > 0) {
let id = a.attr('href');
let name = a.attr('title');
let pic = img.attr('data-src') || img.attr('src');
let remark = $(n).find('span.public-list-prb').text();
videos.push({
vod_id: id,
vod_name: name,
vod_pic: pic,
vod_remarks: remark,
});
}
});
return videos;
}
async function homeVod() {
const html = await request(siteUrl, null, true);
const $ = load(html);
let videos = getVideos($);
return JSON.stringify({
list: videos,
});
}
async function category(tid, pg, filter, extend) {
if (!pg) pg = 1;
let area = extend.area || '';
let by = extend.by || '';
let clazz = extend.class || '';
let lang = extend.lang || '';
let letter = extend.letter || '';
let year = extend.year || '';
let url = siteUrl + `/show/${tid}-${encodeURIComponent(area)}-${encodeURIComponent(by)}-${encodeURIComponent(clazz)}-${encodeURIComponent(lang)}-${encodeURIComponent(letter)}---${pg}---${encodeURIComponent(year)}/`;
const html = await request(url, null, true);
const $ = load(html);
let videos = getVideos($);
return JSON.stringify({
page: parseInt(pg),
pagecount: videos.length === 0 ? parseInt(pg) : parseInt(pg) + 1,
limit: 40,
total: 999,
list: videos,
});
}
async function detail(id) {
try {
let url = siteUrl + id;
const html = await request(url, null, true);
const $ = load(html);
let title = $('h3.slide-info-title').text();
let pic = $('.detail-pic img').attr('data-src');
let infos = $('.slide-info');
let year = '', area = '', clazz = '', remark = '', director = '', actor = '';
infos.each((i, n) => {
let text = $(n).text();
if (text.indexOf('导演') >= 0) {
director = $(n).find('a').map((i, a) => $(a).text()).get().join(', ');
} else if (text.indexOf('演员') >= 0) {
actor = $(n).find('a').map((i, a) => $(a).text()).get().join(', ');
} else if (text.indexOf('备注') >= 0) {
remark = text.replace('备注 :', '').trim();
} else if (text.indexOf('更新') >= 0) {
if(!remark) remark = text.replace('更新 :', '').trim();
} else if (i === 0) {
let remarks = $(n).find('span.slide-info-remarks').map((i, s) => $(s).text().trim()).get();
year = remarks[0] || '';
area = remarks[1] || '';
clazz = $(n).find('a').last().text() || '';
}
});
let content = $('#height_limit').text();
let playFroms = [];
$('.anthology-tab a').each((i, n) => {
playFroms.push($(n).text().trim().replace(/[\d\s]+$/, ''));
});
let playUrls = [];
$('.anthology-list-play').each((i, list) => {
let urls = [];
$(list).find('li a').each((j, a) => {
urls.push($(a).text().trim() + '$' + $(a).attr('href'));
});
playUrls.push(urls.join('#'));
});
let video = {
vod_id: id,
vod_name: title,
vod_pic: pic,
vod_year: year,
vod_area: area,
vod_class: clazz,
vod_remarks: remark,
vod_director: director,
vod_actor: actor,
vod_content: content,
vod_play_from: playFroms.join('$$$'),
vod_play_url: playUrls.join('$$$')
};
return JSON.stringify({ list: [video] });
} catch (e) {}
return null;
}
async function search(wd, quick, pg) {
if (!pg) pg = 1;
let url = siteUrl + `/ss/${encodeURIComponent(wd)}----------${pg}---/`;
const html = await request(url, null, true);
const $ = load(html);
let videos = [];
$('.search-box').each((i, n) => {
let a = $(n).find('a.public-list-exp');
let img = $(n).find('img.lazy');
let id = a.attr('href');
let name = $(n).find('.thumb-txt a').text();
let pic = img.attr('data-src');
let remark = $(n).find('span.public-list-prb').text();
videos.push({
vod_id: id,
vod_name: name,
vod_pic: pic,
vod_remarks: remark,
});
});
return JSON.stringify({
page: parseInt(pg),
pagecount: videos.length === 0 ? parseInt(pg) : parseInt(pg) + 1,
list: videos,
});
}
function base64Decode(text) {
return Crypto.enc.Utf8.stringify(Crypto.enc.Base64.parse(text));
}
async function play(flag, id, flags) {
let playUrl = '';
try {
let playPage = siteUrl + id;
let html = await request(playPage, null, true);
let match = html.match(/var player_aaaa=(.*?)<\/script>/s);
if (!match) {
return JSON.stringify({ parse: 1, url: id });
}
let player = JSON.parse(match[1].trim().replace(/;$/, ''));
playUrl = player.url || '';
let next = player.link_next || '';
let title = '在线观看';
if (player.vod_data && player.vod_data.vod_name) {
let nid = player.nid ? player.nid : '';
title = '剧集《' + player.vod_data.vod_name + '》' + nid + '在线观看';
}
if (player.encrypt == 1) {
playUrl = unescape(playUrl);
} else if (player.encrypt == 2) {
playUrl = unescape(base64Decode(playUrl));
}
if (/\.m3u8|\.mp4/i.test(playUrl)) {
return JSON.stringify({
parse: 0,
url: playUrl,
headers: { "User-Agent": headers['User-Agent'] }
});
}
let nextUrl = siteUrl + next.replace(/\\\//g, '/');
let jxUrl = "https://play.brovod.com/?url=" + encodeURIComponent(playUrl) + "&next=" + encodeURIComponent(nextUrl) + "&title=" + encodeURIComponent(title);
let jx = await req(jxUrl, {
method: 'get',
headers: {
"User-Agent": headers['User-Agent'],
"Referer": playPage
}
});
let configMatch = jx.content.match(/var config\s*=\s*(\{[\s\S]*?\})\s*(?:;|<\/script>)/);
if (!configMatch) {
return JSON.stringify({ parse: 1, url: playUrl });
}
let configStr = configMatch[1].replace(/,\s*\}/g, '}');
let config = JSON.parse(configStr);
let t = new Date();
t.setMinutes(0, 0, 0);
let hourlyStamp = Math.floor(t.getTime() / 1000);
let key = Crypto.SHA256(hourlyStamp + "cnmdhb").toString(Crypto.enc.Hex).toLowerCase();
let postData = {
url: config.url.replace(/%20/g, '+'),
pbgjz: config.pbgjz || '',
dmkey: config.dmkey || '',
key: key
};
let result = await req("https://play.brovod.com/JX", {
method: "post",
headers: {
"User-Agent": headers['User-Agent'],
"Referer": "https://play.brovod.com/",
"Origin": "https://play.brovod.com",
"Accept": "application/json, text/javascript, */*; q=0.01",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest"
},
data: JSON.stringify(postData),
postType: ""
});
let json = JSON.parse(result.content);
let finalUrl = json.cnmdhb || json.url || '';
if (finalUrl) {
return JSON.stringify({
parse: 0,
url: finalUrl,
headers: { "User-Agent": headers['User-Agent'] }
});
}
return JSON.stringify({ parse: 1, url: playUrl });
} catch (e) {
return JSON.stringify({ parse: 1, url: playUrl || id });
}
}
function genFilterObj() {
return {
"Movies": [
{"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": "冒险"}, {"n": "枪战", "v": "枪战"}, {"n": "恐怖", "v": "恐怖"}, {"n": "悬疑", "v": "悬疑"}, {"n": "惊悚", "v": "惊悚"}, {"n": "经典", "v": "经典"}, {"n": "青春", "v": "青春"}, {"n": "家庭", "v": "家庭"}, {"n": "记录", "v": "记录"}]},
{"key": "area", "name": "地区", "value": [{"n": "全部", "v": ""}, {"n": "大陆", "v": "大陆"}, {"n": "香港", "v": "香港"}, {"n": "台湾", "v": "台湾"}, {"n": "美国", "v": "美国"}, {"n": "法国", "v": "法国"}, {"n": "英国", "v": "英国"}, {"n": "日本", "v": "日本"}, {"n": "韩国", "v": "韩国"}, {"n": "德国", "v": "德国"}, {"n": "泰国", "v": "泰国"}, {"n": "印度", "v": "印度"}, {"n": "意大利", "v": "意大利"}, {"n": "西班牙", "v": "西班牙"}, {"n": "加拿大", "v": "加拿大"}]},
{"key": "year", "name": "年份", "value": [{"n": "全部", "v": ""}, {"n": "2025", "v": "2025"}, {"n": "2024", "v": "2024"}, {"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"}]},
{"key": "lang", "name": "语言", "value": [{"n": "全部", "v": ""}, {"n": "国语", "v": "国语"}, {"n": "英语", "v": "英语"}, {"n": "粤语", "v": "粤语"}, {"n": "韩语", "v": "韩语"}, {"n": "日语", "v": "日语"}, {"n": "法语", "v": "法语"}]},
{"key": "by", "name": "排序", "value": [{"n": "时间", "v": "time"}, {"n": "人气", "v": "hits"}, {"n": "评分", "v": "score"}]},
{"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"}]}
],
"TV": [
{"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": "经典"}, {"n": "情景", "v": "情景"}, {"n": "商战", "v": "商战"}, {"n": "网剧", "v": "网剧"}]},
{"key": "area", "name": "地区", "value": [{"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": "2025", "v": "2025"}, {"n": "2024", "v": "2024"}, {"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"}]},
{"key": "lang", "name": "语言", "value": [{"n": "全部", "v": ""}, {"n": "国语", "v": "国语"}, {"n": "英语", "v": "英语"}, {"n": "粤语", "v": "粤语"}, {"n": "韩语", "v": "韩语"}, {"n": "日语", "v": "日语"}]},
{"key": "by", "name": "排序", "value": [{"n": "时间", "v": "time"}, {"n": "人气", "v": "hits"}, {"n": "评分", "v": "score"}]},
{"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"}]}
],
"Shows": [
{"key": "class", "name": "剧情", "value": [{"n": "全部", "v": ""}, {"n": "脱口秀", "v": "脱口秀"}, {"n": "真人秀", "v": "真人秀"}, {"n": "选秀", "v": "选秀"}, {"n": "美食", "v": "美食"}, {"n": "旅游", "v": "旅游"}, {"n": "访谈", "v": "访谈"}, {"n": "播报", "v": "播报"}]},
{"key": "area", "name": "地区", "value": [{"n": "全部", "v": ""}, {"n": "大陆", "v": "大陆"}, {"n": "韩国", "v": "韩国"}, {"n": "香港", "v": "香港"}, {"n": "台湾", "v": "台湾"}, {"n": "日本", "v": "日本"}, {"n": "美国", "v": "美国"}]},
{"key": "year", "name": "年份", "value": [{"n": "全部", "v": ""}, {"n": "2025", "v": "2025"}, {"n": "2024", "v": "2024"}, {"n": "2023", "v": "2023"}, {"n": "2022", "v": "2022"}, {"n": "2021", "v": "2021"}, {"n": "2020", "v": "2020"}]},
{"key": "by", "name": "排序", "value": [{"n": "时间", "v": "time"}, {"n": "人气", "v": "hits"}, {"n": "评分", "v": "score"}]}
],
"Anime": [
{"key": "class", "name": "剧情", "value": [{"n": "全部", "v": ""}, {"n": "热血", "v": "热血"}, {"n": "格斗", "v": "格斗"}, {"n": "恋爱", "v": "恋爱"}, {"n": "校园", "v": "校园"}, {"n": "搞笑", "v": "搞笑"}, {"n": "玄幻", "v": "玄幻"}, {"n": "剧情", "v": "剧情"}, {"n": "战争", "v": "战争"}, {"n": "仙侠", "v": "仙侠"}]},
{"key": "area", "name": "地区", "value": [{"n": "全部", "v": ""}, {"n": "大陆", "v": "大陆"}, {"n": "日本", "v": "日本"}, {"n": "美国", "v": "美国"}]},
{"key": "year", "name": "年份", "value": [{"n": "全部", "v": ""}, {"n": "2025", "v": "2025"}, {"n": "2024", "v": "2024"}, {"n": "2023", "v": "2023"}, {"n": "2022", "v": "2022"}, {"n": "2021", "v": "2021"}, {"n": "2020", "v": "2020"}]},
{"key": "by", "name": "排序", "value": [{"n": "时间", "v": "time"}, {"n": "人气", "v": "hits"}, {"n": "评分", "v": "score"}]}
],
"Snaps": [
{"key": "year", "name": "年份", "value": [{"n": "全部", "v": ""}, {"n": "2025", "v": "2025"}, {"n": "2024", "v": "2024"}, {"n": "2023", "v": "2023"}]},
{"key": "by", "name": "排序", "value": [{"n": "时间", "v": "time"}, {"n": "人气", "v": "hits"}, {"n": "评分", "v": "score"}]}
],
"Documentaries": [
{"key": "area", "name": "地区", "value": [{"n": "全部", "v": ""}, {"n": "大陆", "v": "大陆"}, {"n": "美国", "v": "美国"}, {"n": "英国", "v": "英国"}]},
{"key": "year", "name": "年份", "value": [{"n": "全部", "v": ""}, {"n": "2025", "v": "2025"}, {"n": "2024", "v": "2024"}, {"n": "2023", "v": "2023"}]}
]
};
}
export function __jsEvalReturn() {
return {
init: init,
home: home,
homeVod: homeVod,
category: category,
detail: detail,
play: play,
search: search,
};
}
+221
View File
@@ -0,0 +1,221 @@
var HOST = "http://mtyy.lizhun.xn--6qq986b3xl";
var KEY = "d3799pudaccmtyyo";
var HEADERS = {
"User-Agent": "okhttp/3.14.9",
"App-Device-Id": "00000000000000000000000000000000",
"App-Os-Type": "android",
"App-Ui-Mode": "light",
"App-Version-Code": "200",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
};
var HOME = null;
function text(value) {
if (typeof value === "string") return value;
if (!value) return "";
var body = value.content || value.body || value.data || "";
return typeof body === "string" ? body : JSON.stringify(body);
}
function json(value) {
return JSON.stringify(value);
}
function form(data) {
var values = [];
data = data || {};
Object.keys(data).forEach(function (key) {
values.push(encodeURIComponent(key) + "=" + encodeURIComponent(data[key] == null ? "" : data[key]));
});
return values.join("&");
}
function decrypt(value) {
try {
if (typeof aesX === "function") return JSON.parse(aesX("AES/CBC/PKCS5", false, value, true, KEY, KEY, false));
if (typeof CryptoJS !== "undefined") {
var key = CryptoJS.enc.Utf8.parse(KEY);
var plain = CryptoJS.AES.decrypt(value, key, {iv: key, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7}).toString(CryptoJS.enc.Utf8);
return JSON.parse(plain);
}
} catch (e) {}
return {};
}
function api(path, data) {
try {
var response = req(HOST + "/api/vod/" + path, {method: "POST", headers: HEADERS, body: form(data), timeout: 20000});
var outer = JSON.parse(text(response) || "{}");
if (Number(outer.code) !== 0) return {};
return typeof outer.data === "string" ? decrypt(outer.data) : outer.data || {};
} catch (e) {
return {};
}
}
function getHome() {
if (!HOME) HOME = api("init", {});
return HOME || {};
}
function vod(item) {
item = item || {};
return {
vod_id: String(item.vod_id || ""),
vod_name: item.vod_name || "",
vod_pic: item.vod_pic || "",
vod_remarks: item.vod_remarks || ""
};
}
function filters(types) {
var names = {"class": "类型", "area": "地区", "lang": "语言", "year": "年份", "sort": "排序"};
var result = {};
(types || []).forEach(function (type) {
var values = [];
(type.filter_type_list || []).forEach(function (group) {
var options = [];
(group.list || []).forEach(function (item) {
var value = String(item);
options.push({n: value, v: value === "全部" ? "" : value});
});
if (group.name && options.length) values.push({key: group.name, name: names[group.name] || group.name, value: options});
});
if (values.length) result[String(type.type_id)] = values;
});
return result;
}
function playId(vodId, source, episode) {
return encodeURIComponent(JSON.stringify({
v: String(vodId),
s: String(source.id || ""),
e: Number(episode.episode_index || 0),
p: Number(source.player_parse_type || 1),
a: source.parse_api || "",
u: episode.url || ""
}));
}
function init(ext) {
var value = ext;
if (value && typeof value === "object") value = value.ext || value.host || "";
if (typeof value === "string" && /^https?:\/\//.test(value)) HOST = value.replace(/\/$/, "");
HOME = null;
}
function home(filter) {
var data = getHome();
var types = data.type_list || [];
var classes = types.map(function (item) {
return {type_id: String(item.type_id || ""), type_name: item.type_name || ""};
}).filter(function (item) {
return item.type_id && item.type_name;
});
if (!classes.length) classes = [{type_id: "20", type_name: "电影"}, {type_id: "21", type_name: "电视剧"}, {type_id: "22", type_name: "动漫"}, {type_id: "24", type_name: "综艺"}];
return json({"class": classes, filters: filters(types)});
}
function homeVod() {
var data = getHome();
var types = data.type_list || [];
var values = (data.banner_list || []).concat(data.recommend_list || []);
types.forEach(function (type) {
values = values.concat((type.recommend_list || []).slice(0, 3));
});
var seen = {};
var list = [];
values.forEach(function (item) {
var value = vod(item);
if (value.vod_id && !seen[value.vod_id]) {
seen[value.vod_id] = true;
list.push(value);
}
});
return json({list: list});
}
function category(tid, pg, filter, extend) {
var page = parseInt(pg || 1) || 1;
var ext = extend && typeof extend === "object" ? extend : {};
if (typeof extend === "string") try { ext = JSON.parse(extend); } catch (e) {}
var params = {type_id: tid, page: page};
["class", "area", "lang", "year", "sort"].forEach(function (key) {
if (ext[key]) params[key] = ext[key];
});
var data = api("typeFilterVodList", params);
var list = (data.recommend_list || []).map(vod);
var limit = Number(data.page_size || 36);
var total = Number(data.total || 0);
var pagecount = total ? Math.max(page, Math.ceil(total / limit)) : page + (list.length >= limit ? 1 : 0);
return json({page: page, pagecount: pagecount, limit: limit, total: total, list: list});
}
function detail(id) {
var value = Array.isArray(id) ? id[0] : id;
var vodId = String(value || "").split("@@")[0];
if (vodId.indexOf("$") >= 0) vodId = vodId.split("$").pop();
var data = api("vodDetail", {vod_id: vodId});
var info = data.vod || {};
if (!info.vod_id) return json({list: []});
var sources = {};
(data.player_source_list || []).forEach(function (source) {
sources[source.player_code] = source;
});
var from = [];
var urls = [];
(data.vod_play_url_list || []).forEach(function (group) {
var source = sources[group.player_code] || {};
if (!source.id || (Number(source.player_parse_type || 1) !== 1 && !source.parse_api)) return;
var episodes = [];
(group.urls || []).forEach(function (episode) {
var name = String(episode.name || Number(episode.episode_index || 0) + 1).replace(/[$#]/g, " ");
episodes.push(name + "$" + playId(vodId, source, episode));
});
if (!episodes.length) return;
from.push(String(source.player_name || group.player_code || "线路").replace(/[$#]/g, " "));
urls.push(episodes.join("#"));
});
var item = vod(info);
item.vod_actor = info.vod_actor || "";
item.vod_director = info.vod_director || "";
item.vod_area = info.vod_area || "";
item.vod_year = info.vod_year || "";
item.vod_content = info.vod_content || info.vod_blurb || "";
item.vod_play_from = from.join("$$$");
item.vod_play_url = urls.join("$$$");
return json({list: [item]});
}
function search(wd, quick, pg) {
var page = parseInt(pg || 1) || 1;
var data = api("searchList", {keywords: wd, type_id: 0, page: page});
var list = (data.search_list || []).map(vod);
return json({page: page, pagecount: list.length ? page + 1 : page, limit: list.length || 20, total: list.length, list: list});
}
function play(flag, id, flags) {
try {
var value = JSON.parse(decodeURIComponent(String(id || "")));
if (Number(value.p) === 1) {
var parsed = api("vodParse", {vod_id: value.v, player_source_id: value.s, episode_index: value.e, scene: 0});
var serverUrl = parsed.play_url || "";
if (serverUrl) return json({parse: /\.(m3u8|mp4|flv)(\?|$)/i.test(serverUrl) ? 0 : 1, url: serverUrl, header: HEADERS, headers: HEADERS});
}
var url = value.u || "";
if (/\.(m3u8|mp4|flv)(\?|$)/i.test(url)) return json({parse: 0, url: url, header: HEADERS, headers: HEADERS});
if (value.a) {
var parserUrl = value.a + encodeURIComponent(url);
try {
var parser = JSON.parse(text(req(parserUrl, {method: "GET", headers: HEADERS, timeout: 20000})) || "{}");
if (parser.url) return json({parse: 0, url: parser.url, header: HEADERS, headers: HEADERS});
} catch (e) {}
return json({parse: 1, jx: 0, url: parserUrl, header: HEADERS, headers: HEADERS});
}
return json({parse: 1, jx: 0, url: url, header: HEADERS, headers: HEADERS});
} catch (e) {
return json({parse: 0, url: ""});
}
}
__JS_SPIDER__ = {init: init, home: home, homeVod: homeVod, category: category, detail: detail, search: search, play: play};