增加网络直播

This commit is contained in:
mtvpls
2026-01-20 11:48:41 +08:00
parent 5e9ecc20f0
commit 78f7c68ef5
8 changed files with 585 additions and 0 deletions
+124
View File
@@ -0,0 +1,124 @@
import { NextRequest, NextResponse } from 'next/server';
import { getAuthInfoFromCookie } from '@/lib/auth';
import { getConfig } from '@/lib/config';
import { db } from '@/lib/db';
export async function POST(request: NextRequest) {
try {
const authInfo = getAuthInfoFromCookie(request);
const username = authInfo?.username;
const config = await getConfig();
if (username !== process.env.USERNAME) {
const userInfo = await db.getUserInfoV2(username || '');
if (!userInfo || userInfo.role !== 'admin' || userInfo.banned) {
return NextResponse.json({ error: '权限不足' }, { status: 401 });
}
}
const body = await request.json();
const { action } = body;
if (!config) {
return NextResponse.json({ error: '配置不存在' }, { status: 404 });
}
if (!config.WebLiveConfig) {
config.WebLiveConfig = [];
}
switch (action) {
case 'add': {
const { name, platform, roomId } = body;
if (!name || !platform || !roomId) {
return NextResponse.json({ error: '缺少必要参数' }, { status: 400 });
}
const key = `web_${Date.now()}`;
if (config.WebLiveConfig.some((s) => s.key === key)) {
return NextResponse.json({ error: 'Key已存在' }, { status: 400 });
}
config.WebLiveConfig.push({
key,
name,
platform,
roomId,
from: 'custom',
disabled: false,
});
break;
}
case 'delete': {
const { key } = body;
const source = config.WebLiveConfig.find((s) => s.key === key);
if (!source) {
return NextResponse.json({ error: '源不存在' }, { status: 404 });
}
if (source.from === 'config') {
return NextResponse.json({ error: '无法删除配置文件中的源' }, { status: 400 });
}
config.WebLiveConfig = config.WebLiveConfig.filter((s) => s.key !== key);
break;
}
case 'enable': {
const { key } = body;
const source = config.WebLiveConfig.find((s) => s.key === key);
if (!source) {
return NextResponse.json({ error: '源不存在' }, { status: 404 });
}
source.disabled = false;
break;
}
case 'disable': {
const { key } = body;
const source = config.WebLiveConfig.find((s) => s.key === key);
if (!source) {
return NextResponse.json({ error: '源不存在' }, { status: 404 });
}
source.disabled = true;
break;
}
case 'edit': {
const { key, name, platform, roomId } = body;
const source = config.WebLiveConfig.find((s) => s.key === key);
if (!source) {
return NextResponse.json({ error: '源不存在' }, { status: 404 });
}
if (source.from === 'config') {
return NextResponse.json({ error: '无法编辑配置文件中的源' }, { status: 400 });
}
source.name = name;
source.platform = platform;
source.roomId = roomId;
break;
}
case 'sort': {
const { keys } = body;
if (!Array.isArray(keys)) {
return NextResponse.json({ error: '无效的排序数据' }, { status: 400 });
}
const sortedSources = keys
.map((key) => config.WebLiveConfig!.find((s) => s.key === key))
.filter((s) => s !== undefined);
config.WebLiveConfig = sortedSources;
break;
}
default:
return NextResponse.json({ error: '未知操作' }, { status: 400 });
}
await db.saveAdminConfig(config);
return NextResponse.json({ success: true });
} catch (error) {
return NextResponse.json(
{ error: error instanceof Error ? error.message : '操作失败' },
{ status: 500 }
);
}
}
+19
View File
@@ -0,0 +1,19 @@
import { NextRequest, NextResponse } from 'next/server';
import { getConfig } from '@/lib/config';
export async function GET(request: NextRequest) {
try {
const config = await getConfig();
if (!config?.WebLiveConfig) {
return NextResponse.json([]);
}
const sources = config.WebLiveConfig.filter(s => !s.disabled);
return NextResponse.json(sources);
} catch (error) {
return NextResponse.json(
{ error: error instanceof Error ? error.message : '获取失败' },
{ status: 500 }
);
}
}
+33
View File
@@ -0,0 +1,33 @@
import { NextRequest, NextResponse } from 'next/server';
export async function GET(request: NextRequest) {
try {
const { searchParams } = new URL(request.url);
const platform = searchParams.get('platform');
const roomId = searchParams.get('roomId');
if (!platform || !roomId) {
return NextResponse.json({ error: '缺少参数' }, { status: 400 });
}
if (platform === 'huya') {
const res = await fetch(`https://mp.huya.com/cache.php?m=Live&do=profileRoom&roomid=${roomId}`);
const data = await res.json();
if (data.status === 200 && data.data?.liveStatus === 'ON') {
const stream = data.data.stream;
const url = `${stream.flv.multiLine[0].url}/${stream.flv.streamName}.${stream.flv.sFlvUrlSuffix}?${stream.flv.sFlvAntiCode}`;
return NextResponse.json({ url });
}
return NextResponse.json({ error: '直播未开启' }, { status: 404 });
}
return NextResponse.json({ error: '不支持的平台' }, { status: 400 });
} catch (error) {
return NextResponse.json(
{ error: error instanceof Error ? error.message : '获取失败' },
{ status: 500 }
);
}
}