// 获取弹幕 API 路由 import { NextRequest, NextResponse } from 'next/server'; import { getConfig } from '@/lib/config'; export const runtime = 'nodejs'; // 解析弹幕 XML 为 JSON function parseXmlDanmaku(xmlText: string): Array<{ p: string; m: string; cid: number }> { const comments: Array<{ p: string; m: string; cid: number }> = []; // 使用正则表达式提取所有 标签 const dTagRegex = /]*>([^<]*)<\/d>/g; let match; while ((match = dTagRegex.exec(xmlText)) !== null) { const p = match[1]; const m = match[2]; // 从 p 属性中提取 cid(弹幕ID) const pParts = p.split(','); const cid = pParts[7] ? parseInt(pParts[7]) : 0; comments.push({ p, m, cid, }); } return comments; } export async function GET(request: NextRequest) { try { const searchParams = request.nextUrl.searchParams; const episodeId = searchParams.get('episodeId'); const url = searchParams.get('url'); // 至少需要一个参数 if (!episodeId && !url) { return NextResponse.json( { count: 0, comments: [], }, { status: 400 } ); } // 从数据库读取弹幕配置 const config = await getConfig(); const { DanmakuApiBase, DanmakuApiToken } = config.SiteConfig; // 构建 API URL const baseUrl = DanmakuApiToken === '87654321' ? DanmakuApiBase : `${DanmakuApiBase}/${DanmakuApiToken}`; let apiUrl: string; if (episodeId) { // 通过剧集 ID 获取弹幕 - 使用 XML 格式 apiUrl = `${baseUrl}/api/v2/comment/${episodeId}?format=xml`; } else { // 通过视频 URL 获取弹幕 - 使用 XML 格式 apiUrl = `${baseUrl}/api/v2/comment?url=${encodeURIComponent(url!)}&format=xml`; } const response = await fetch(apiUrl, { method: 'GET', headers: { 'Accept': 'application/xml, text/xml', }, }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } // 获取 XML 文本 const xmlText = await response.text(); // 解析 XML 为 JSON const comments = parseXmlDanmaku(xmlText); return NextResponse.json({ count: comments.length, comments, }); } catch (error) { console.error('获取弹幕代理错误:', error); return NextResponse.json( { count: 0, comments: [], }, { status: 500 } ); } }