Ship composition families, optional background images for lower-corner templates, and an optional blurred cover fill for classic letterbox.
86 lines
2.8 KiB
TypeScript
86 lines
2.8 KiB
TypeScript
import { NextResponse } from "next/server";
|
|
import {
|
|
COMPOSITION_FAMILIES,
|
|
LAYOUT_TEMPLATE_LABELS,
|
|
LAYOUT_TEMPLATES,
|
|
} from "@/lib/layout";
|
|
import { API_DOCS_URL } from "@/lib/plans";
|
|
|
|
export async function GET() {
|
|
return NextResponse.json({
|
|
name: "Songs2VID API",
|
|
version: "1.0",
|
|
authentication: "Authorization: Bearer <api_key>",
|
|
requirements: ["YouTube account connected"],
|
|
rateLimit: "100,000 requests per minute per account",
|
|
billing: false,
|
|
notes:
|
|
"OSS self-hosted: full entitlements, no Stripe/credits/paywall. In-repo docs: docs/api/",
|
|
guidance: {
|
|
recommended:
|
|
"For most jobs (especially 5+ audio files): POST /api/v1/upload per file, then POST /api/v1/jobs with the returned paths",
|
|
batch:
|
|
"POST /api/v1/jobs/batch is for small packs only. Large multipart bodies may fail with 'failed to parse body as FormData'",
|
|
},
|
|
layoutTemplates: LAYOUT_TEMPLATES.map((id) => ({
|
|
id,
|
|
label: LAYOUT_TEMPLATE_LABELS[id],
|
|
})),
|
|
compositionFamilies: COMPOSITION_FAMILIES.map((family) => ({
|
|
id: family.id,
|
|
label: family.label,
|
|
defaultTemplate: family.defaultTemplate,
|
|
variants: family.variants.map((id) => ({
|
|
id,
|
|
label: LAYOUT_TEMPLATE_LABELS[id],
|
|
})),
|
|
})),
|
|
endpoints: [
|
|
{
|
|
method: "POST",
|
|
path: "/api/v1/upload",
|
|
description:
|
|
"Upload image, audio, PNG logo, or .ttf/.otf font (font ≤10MB)",
|
|
body: "multipart/form-data: file, type (image|audio|logo|font)",
|
|
},
|
|
{
|
|
method: "POST",
|
|
path: "/api/v1/jobs",
|
|
description:
|
|
"Create a video job from uploaded file paths with layouts, watermark, and per-item covers",
|
|
body: "application/json: { imagePath, items[{ audioPath, audioFilename, metadata }] }",
|
|
},
|
|
{
|
|
method: "POST",
|
|
path: "/api/v1/jobs/batch",
|
|
description:
|
|
"One-shot batch for small packs only; large uploads may fail FormData parsing; prefer upload + jobs",
|
|
body: "multipart/form-data: image, audio[] (repeatable), metadata? (JSON string)",
|
|
},
|
|
{
|
|
method: "GET",
|
|
path: "/api/v1/playlists",
|
|
description: "List YouTube playlists for the authenticated account",
|
|
},
|
|
{
|
|
method: "POST",
|
|
path: "/api/v1/playlists",
|
|
description: "Create a YouTube playlist",
|
|
body: "application/json: { title, description?, privacy? (public|unlisted|private) }",
|
|
},
|
|
{
|
|
method: "GET",
|
|
path: "/api/v1/jobs",
|
|
description: "List recent jobs",
|
|
query: "limit (default 20, max 100)",
|
|
},
|
|
{
|
|
method: "GET",
|
|
path: "/api/v1/jobs/:id",
|
|
description: "Get job status and item details",
|
|
},
|
|
],
|
|
docs: API_DOCS_URL,
|
|
});
|
|
}
|