| 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 }, |
| ); |
| } |
| } |
|
|