feat: 添加 TVBox 配置接口,支持视频源导入及解析功能
This commit is contained in:
@@ -0,0 +1,249 @@
|
||||
import fs from 'fs';
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import path from 'path';
|
||||
|
||||
// 定义配置文件结构
|
||||
interface ApiSite {
|
||||
api: string;
|
||||
name: string;
|
||||
detail?: string;
|
||||
}
|
||||
|
||||
interface ConfigFileStruct {
|
||||
cache_time?: number;
|
||||
api_site: {
|
||||
[key: string]: ApiSite;
|
||||
};
|
||||
}
|
||||
|
||||
// TVBox源格式接口
|
||||
interface TVBoxSource {
|
||||
key: string;
|
||||
name: string;
|
||||
type: number; // 0=影视源, 1=直播源, 3=解析源
|
||||
api: string;
|
||||
searchable?: number; // 0=不可搜索, 1=可搜索
|
||||
quickSearch?: number; // 0=不支持快速搜索, 1=支持快速搜索
|
||||
filterable?: number; // 0=不支持分类筛选, 1=支持分类筛选
|
||||
ext?: string; // 扩展参数
|
||||
jar?: string; // jar包地址
|
||||
playUrl?: string; // 播放解析地址
|
||||
categories?: string[]; // 分类
|
||||
timeout?: number; // 超时时间(秒)
|
||||
}
|
||||
|
||||
interface TVBoxConfig {
|
||||
spider?: string; // 爬虫jar包地址
|
||||
wallpaper?: string; // 壁纸地址
|
||||
lives?: Array<{
|
||||
name: string;
|
||||
type: number;
|
||||
url: string;
|
||||
epg?: string;
|
||||
logo?: string;
|
||||
}>; // 直播源
|
||||
sites: TVBoxSource[]; // 影视源
|
||||
parses?: Array<{
|
||||
name: string;
|
||||
type: number;
|
||||
url: string;
|
||||
ext?: Record<string, unknown>;
|
||||
header?: Record<string, string>;
|
||||
}>; // 解析源
|
||||
flags?: string[]; // 播放标识
|
||||
ijk?: Record<string, unknown>; // IJK播放器配置
|
||||
ads?: string[]; // 广告过滤规则
|
||||
}
|
||||
|
||||
// 读取配置文件
|
||||
function readConfigFile(): ConfigFileStruct {
|
||||
const configPath = path.join(process.cwd(), 'config.json');
|
||||
const raw = fs.readFileSync(configPath, 'utf-8');
|
||||
return JSON.parse(raw) as ConfigFileStruct;
|
||||
}
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
try {
|
||||
const { searchParams } = new URL(request.url);
|
||||
const format = searchParams.get('format') || 'json'; // 支持json和txt格式
|
||||
const host = request.headers.get('host') || 'localhost:3000';
|
||||
const protocol = request.headers.get('x-forwarded-proto') || 'http';
|
||||
const baseUrl = `${protocol}://${host}`;
|
||||
|
||||
// 读取当前配置
|
||||
const config = readConfigFile();
|
||||
if (!config?.api_site) {
|
||||
return NextResponse.json({ error: '配置文件读取失败' }, { status: 500 });
|
||||
}
|
||||
|
||||
// 转换为TVBox格式
|
||||
const tvboxConfig: TVBoxConfig = {
|
||||
// 基础配置
|
||||
spider: '', // 可以根据需要添加爬虫jar包
|
||||
wallpaper: `${baseUrl}/screenshot1.png`, // 使用项目截图作为壁纸
|
||||
|
||||
// 影视源配置
|
||||
sites: Object.entries(config.api_site).map(([key, source]) => ({
|
||||
key: key,
|
||||
name: source.name,
|
||||
type: 0, // 影视源
|
||||
api: source.api,
|
||||
searchable: 1, // 可搜索
|
||||
quickSearch: 1, // 支持快速搜索
|
||||
filterable: 1, // 支持分类筛选
|
||||
ext: source.detail || '', // 详情页地址作为扩展参数
|
||||
timeout: 30, // 30秒超时
|
||||
categories: [
|
||||
"电影", "电视剧", "综艺", "动漫", "纪录片", "短剧"
|
||||
]
|
||||
})),
|
||||
|
||||
// 解析源配置(添加一些常用的解析源)
|
||||
parses: [
|
||||
{
|
||||
name: "Json并发",
|
||||
type: 2,
|
||||
url: "Parallel"
|
||||
},
|
||||
{
|
||||
name: "Json轮询",
|
||||
type: 2,
|
||||
url: "Sequence"
|
||||
},
|
||||
{
|
||||
name: "KatelyaTV内置解析",
|
||||
type: 1,
|
||||
url: `${baseUrl}/api/parse?url=`,
|
||||
ext: {
|
||||
flag: ["qiyi", "qq", "letv", "sohu", "youku", "mgtv", "bilibili", "wasu", "xigua", "1905"]
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
// 播放标识
|
||||
flags: [
|
||||
"youku", "qq", "iqiyi", "qiyi", "letv", "sohu", "tudou", "pptv",
|
||||
"mgtv", "wasu", "bilibili", "le", "duoduozy", "renrenmi", "xigua",
|
||||
"优酷", "腾讯", "爱奇艺", "奇艺", "乐视", "搜狐", "土豆", "PPTV",
|
||||
"芒果", "华数", "哔哩", "1905"
|
||||
],
|
||||
|
||||
// 直播源(可选)
|
||||
lives: [
|
||||
{
|
||||
name: "KatelyaTV直播",
|
||||
type: 0,
|
||||
url: `${baseUrl}/api/live/channels`,
|
||||
epg: "",
|
||||
logo: ""
|
||||
}
|
||||
],
|
||||
|
||||
// 广告过滤规则
|
||||
ads: [
|
||||
"mimg.0c1q0l.cn",
|
||||
"www.googletagmanager.com",
|
||||
"www.google-analytics.com",
|
||||
"mc.usihnbcq.cn",
|
||||
"mg.g1mm3d.cn",
|
||||
"mscs.svaeuzh.cn",
|
||||
"cnzz.hhurm.com",
|
||||
"tp.vinuxhome.com",
|
||||
"cnzz.mmstat.com",
|
||||
"www.baihuillq.com",
|
||||
"s23.cnzz.com",
|
||||
"z3.cnzz.com",
|
||||
"c.cnzz.com",
|
||||
"stj.v1vo.top",
|
||||
"z12.cnzz.com",
|
||||
"img.mosflower.cn",
|
||||
"tips.gamevvip.com",
|
||||
"ehwe.yhdtns.com",
|
||||
"xdn.cqqc3.com",
|
||||
"www.jixunkyy.cn",
|
||||
"sp.chemacid.cn",
|
||||
"hm.baidu.com",
|
||||
"s9.cnzz.com",
|
||||
"z6.cnzz.com",
|
||||
"um.cavuc.com",
|
||||
"mav.mavuz.com",
|
||||
"wofwk.aoidf3.com",
|
||||
"z5.cnzz.com",
|
||||
"xc.hubeijieshikj.cn",
|
||||
"tj.tianwenhu.com",
|
||||
"xg.gars57.cn",
|
||||
"k.jinxiuzhilv.com",
|
||||
"cdn.bootcss.com",
|
||||
"ppl.xunzhuo123.com",
|
||||
"xomk.jiangjunmh.top",
|
||||
"img.xunzhuo123.com",
|
||||
"z1.cnzz.com",
|
||||
"s13.cnzz.com",
|
||||
"xg.huataisangao.cn",
|
||||
"z7.cnzz.com",
|
||||
"xg.huataisangao.cn",
|
||||
"z2.cnzz.com",
|
||||
"s96.cnzz.com",
|
||||
"q11.cnzz.com",
|
||||
"thy.dacedsfa.cn",
|
||||
"xg.whsbpw.cn",
|
||||
"s19.cnzz.com",
|
||||
"z8.cnzz.com",
|
||||
"s4.cnzz.com",
|
||||
"f5w.as12df.top",
|
||||
"ae01.alicdn.com",
|
||||
"www.92424.cn",
|
||||
"k.wudejia.com",
|
||||
"vivovip.mmszxc.top",
|
||||
"qiu.xixiqiu.com",
|
||||
"cdnjs.hnfenxun.com",
|
||||
"cms.qdwght.com"
|
||||
]
|
||||
};
|
||||
|
||||
// 根据format参数返回不同格式
|
||||
if (format === 'txt') {
|
||||
// 返回base64编码的配置(TVBox常用格式)
|
||||
const configStr = JSON.stringify(tvboxConfig, null, 2);
|
||||
const base64Config = Buffer.from(configStr).toString('base64');
|
||||
|
||||
return new NextResponse(base64Config, {
|
||||
headers: {
|
||||
'Content-Type': 'text/plain; charset=utf-8',
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Access-Control-Allow-Methods': 'GET',
|
||||
'Access-Control-Allow-Headers': 'Content-Type',
|
||||
'Cache-Control': 'public, max-age=3600'
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 返回JSON格式
|
||||
return NextResponse.json(tvboxConfig, {
|
||||
headers: {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Access-Control-Allow-Methods': 'GET',
|
||||
'Access-Control-Allow-Headers': 'Content-Type',
|
||||
'Cache-Control': 'public, max-age=3600'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
return NextResponse.json(
|
||||
{ error: 'TVBox配置生成失败', details: error instanceof Error ? error.message : String(error) },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 支持CORS预检请求
|
||||
export async function OPTIONS() {
|
||||
return new NextResponse(null, {
|
||||
status: 200,
|
||||
headers: {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Access-Control-Allow-Methods': 'GET, OPTIONS',
|
||||
'Access-Control-Allow-Headers': 'Content-Type',
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user