Ship composition families, optional background images for lower-corner templates, and an optional blurred cover fill for classic letterbox.
123 lines
3.4 KiB
TypeScript
123 lines
3.4 KiB
TypeScript
import { Privacy } from "@prisma/client";
|
|
import type { LayoutSettings } from "./layout";
|
|
import type { WatermarkSettings } from "./watermark";
|
|
|
|
export type ItemMetadata = {
|
|
title: string;
|
|
description: string;
|
|
tags: string;
|
|
privacy: Privacy;
|
|
categoryId: string;
|
|
resolution: string;
|
|
notifySubscribers: boolean;
|
|
madeForKids: boolean;
|
|
embeddable: boolean;
|
|
creativeCommons: boolean;
|
|
/** Legacy toggle — default Songs2VID branding when watermark.mode is omitted. */
|
|
includeWatermark: boolean;
|
|
/** YouTube playlist ID. Video is added after upload. */
|
|
playlistId?: string | null;
|
|
/**
|
|
* Optional per-item cover image path.
|
|
* When omitted, the job-level shared imagePath is used.
|
|
*/
|
|
imagePath?: string | null;
|
|
/**
|
|
* Optional full-frame background for LOWER_LEFT / LOWER_RIGHT templates.
|
|
* Blur/opacity apply to this image; cover stays the sharp corner square.
|
|
*/
|
|
backgroundImagePath?: string | null;
|
|
background_image_path?: string | null;
|
|
/** Custom branding watermark settings. */
|
|
watermark?: Partial<WatermarkSettings> | null;
|
|
/** Artist line for art-track layouts (on-video only). */
|
|
artist?: string | null;
|
|
/** Song / track title burned into art-track layouts (on-video only). */
|
|
songTitle?: string | null;
|
|
/**
|
|
* Art-track layout. Prefer camelCase; snake_case aliases accepted:
|
|
* layout_template, blur_amount, text_padding.
|
|
* `template`: COVER_LEFT_TEXT_RIGHT | COVER_TOP_TEXT_BOTTOM |
|
|
* COVER_RIGHT_TEXT_LEFT | CENTERED_COMPACT | LOWER_LEFT_COVER_TEXT |
|
|
* LOWER_RIGHT_COVER_TEXT (also listed on GET /api/v1 → layoutTemplates).
|
|
*/
|
|
layout?: Partial<LayoutSettings> & {
|
|
layoutTemplate?: string | null;
|
|
layout_template?: string | null;
|
|
blur_fill?: boolean;
|
|
blur_amount?: number;
|
|
blur_opacity?: number;
|
|
text_padding?: number;
|
|
title_artist_gap?: number;
|
|
text_offset_x?: number;
|
|
text_offset_y?: number;
|
|
title_bold?: boolean;
|
|
} | null;
|
|
/** Flat aliases (also accepted). */
|
|
layoutTemplate?: string | null;
|
|
layout_template?: string | null;
|
|
blurFill?: boolean;
|
|
blur_fill?: boolean;
|
|
blurAmount?: number;
|
|
blur_amount?: number;
|
|
blurOpacity?: number;
|
|
blur_opacity?: number;
|
|
textPadding?: number;
|
|
text_padding?: number;
|
|
titleArtistGap?: number;
|
|
title_artist_gap?: number;
|
|
textOffsetX?: number;
|
|
text_offset_x?: number;
|
|
textOffsetY?: number;
|
|
text_offset_y?: number;
|
|
titleBold?: boolean;
|
|
title_bold?: boolean;
|
|
};
|
|
|
|
export type UploadedAudio = {
|
|
path: string;
|
|
filename: string;
|
|
metadata: ItemMetadata;
|
|
};
|
|
|
|
export type CreatePlaylistRequest = {
|
|
title: string;
|
|
description?: string;
|
|
privacy?: "public" | "unlisted" | "private";
|
|
};
|
|
|
|
export type CreateJobPayload = {
|
|
/** Shared cover for Free / default when items omit imagePath. */
|
|
imagePath: string;
|
|
items: Array<{
|
|
audioPath: string;
|
|
audioFilename: string;
|
|
metadata: ItemMetadata;
|
|
}>;
|
|
/** Create a new playlist and attach its ID to every item (Pro). */
|
|
createPlaylist?: CreatePlaylistRequest | null;
|
|
};
|
|
|
|
export type JobItemResponse = {
|
|
id: string;
|
|
audioFilename: string;
|
|
title: string;
|
|
status: string;
|
|
youtubeVideoId: string | null;
|
|
error: string | null;
|
|
};
|
|
|
|
export type JobResponse = {
|
|
id: string;
|
|
status: string;
|
|
createdAt: string;
|
|
completedAt: string | null;
|
|
items: JobItemResponse[];
|
|
};
|
|
|
|
export type VideoJobData = {
|
|
jobItemId: string;
|
|
userId: string;
|
|
jobId: string;
|
|
};
|