import { NextRequest, NextResponse } from "next/server"; import fs from "fs/promises"; import path from "path"; import { v4 as uuidv4 } from "uuid"; import { DEFAULT_ANIMATION, DEFAULT_LAYOUT, DEFAULT_STYLE, } from "@/lib/defaults"; import { extractVideoMeta } from "@/lib/ffmpeg"; import { ensureStorageDirs, saveProject, uploadDir, videoPath, } from "@/lib/storage"; import type { Project } from "@/types"; export const runtime = "nodejs"; export const maxDuration = 120; const MAX_SIZE = 500 * 1024 * 1024; const MAX_DURATION = 5 * 60; export async function POST(req: NextRequest) { try { await ensureStorageDirs(); const formData = await req.formData(); const file = formData.get("video"); if (!file || !(file instanceof File)) { return NextResponse.json({ error: "No video file provided" }, { status: 400 }); } if (file.size > MAX_SIZE) { return NextResponse.json({ error: "File exceeds 500MB limit" }, { status: 400 }); } const id = uuidv4(); const dir = uploadDir(id); await fs.mkdir(dir, { recursive: true }); const ext = path.extname(file.name).toLowerCase() || ".mp4"; const savedPath = path.join(dir, `video${ext}`); const buffer = Buffer.from(await file.arrayBuffer()); await fs.writeFile(savedPath, buffer); const mp4Path = videoPath(id); if (savedPath !== mp4Path) { await fs.copyFile(savedPath, mp4Path); } const videoMeta = await extractVideoMeta(mp4Path); if (videoMeta.duration > MAX_DURATION) { await fs.rm(dir, { recursive: true, force: true }); return NextResponse.json({ error: "Video exceeds 5 minute limit" }, { status: 400 }); } const project: Project = { id, videoPath: mp4Path, videoMeta, captions: [], style: DEFAULT_STYLE, layout: DEFAULT_LAYOUT, animation: DEFAULT_ANIMATION, status: "draft", createdAt: new Date().toISOString(), }; await saveProject(project); return NextResponse.json({ id, meta: videoMeta }); } catch (error) { console.error("Upload error:", error); return NextResponse.json( { error: error instanceof Error ? error.message : "Upload failed" }, { status: 500 }, ); } }