feat: 添加 TVBox 配置接口,支持视频源导入及解析功能

This commit is contained in:
katelya
2025-09-03 19:32:24 +08:00
parent b4ebe89292
commit 2294f1b066
6 changed files with 864 additions and 1 deletions
+249
View File
@@ -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',
}
});
}