import { remoteAudioCapabilities } from "@/lib/video-canvas/smart-edit/remote-audio"; import { auth } from "@/app/(auth)/auth"; import { NextResponse } from "next/server"; import { execFile } from "node:child_process"; import { promisify } from "node:util"; import path from "node:path"; import { getEnabledAiModelsWithProvider } from "@/lib/db/queries"; import { isCanvasVisionModel } from "@/lib/video-canvas/model-matching"; import { remoteRenderConfig } from "@/lib/video-canvas/smart-edit/remote-render"; export async function GET() { const session = await auth(); if (!session?.user?.id) return NextResponse.json({ error: "未登录" }, { status: 401 }); try { let capabilities = { separation: false, scenes: false, beats: false, asr: false, ffmpeg: false, ffprobe: false, }; try { const { stdout } = await promisify(execFile)( process.env.SMART_EDIT_PYTHON || "python3", [path.resolve("services/smart-edit/analyze.py"), "--check"], { timeout: 10000, maxBuffer: 65536 } ); capabilities = JSON.parse(stdout); } catch {} const audio = await remoteAudioCapabilities(); if (audio) capabilities = { ...capabilities, ...audio }; let renderAvailable = capabilities.ffmpeg; const remote = remoteRenderConfig(); if (remote) { try { const response = await fetch(remote.base + "/health", { headers: { authorization: "Bearer " + remote.token }, signal: AbortSignal.timeout(3000), redirect: "error", cache: "no-store", }); renderAvailable = response.ok && (await response.json()).status === "ok"; } catch { renderAvailable = false; } } const models = (await getEnabledAiModelsWithProvider(false)) .filter((item) => isCanvasVisionModel({ ...item.model, providerType: item.provider.type }) ) .map(({ model }) => ({ id: model.id, name: model.displayName, modelId: model.modelId, })); return NextResponse.json( { capabilities: { ...capabilities, render: renderAvailable }, models }, { headers: { "Cache-Control": "no-store" } } ); } catch { return NextResponse.json( { error: "剪辑服务配置读取失败" }, { status: 503 } ); } }