@henteko/kumiki
Version:
A video generation tool that creates videos from JSON configurations
187 lines • 6 kB
JavaScript
import { z } from "zod";
export const voice = z.object({
languageCode: z.string(),
name: z.string(),
speakingRate: z.number().gte(0.25).lte(4).optional().default(1),
pitch: z.number().gte(-20).lte(20).optional().default(0),
volumeGainDb: z.number().gte(-96).lte(16).optional().default(0),
});
export const volumeMix = z.object({
narration: z.number().nonnegative().lte(1).default(0.8),
bgm: z.number().nonnegative().lte(1).default(0.3),
});
export const narrationDefaults = z.object({
voice: voice.optional(),
volumeMix: volumeMix.optional(),
});
export const projectSettings = z.object({
resolution: z.string().regex(/^\d+x\d+$/),
fps: z.number().int().gte(1).lte(120),
duration: z
.union([z.number().int().gte(-2147483648).lte(2147483647), z.null()])
.optional(),
narrationDefaults: narrationDefaults.optional(),
});
export const background = z.object({
type: z.union([
z.literal("color"),
z.literal("image"),
z.literal("gradient")
]),
value: z.string(),
});
export const transition = z.object({
type: z.union([z.literal("fade"), z.literal("wipe"), z.literal("dissolve")]),
duration: z.number().gte(0.1),
direction: z
.union([
z.literal("left"),
z.literal("right"),
z.literal("up"),
z.literal("down")
])
.optional(),
});
export const narrationTiming = z.object({
delay: z.number().nonnegative().optional().default(0),
fadeIn: z.number().nonnegative().optional().default(0),
fadeOut: z.number().nonnegative().optional().default(0),
});
export const narration = z.object({
text: z.string(),
voice: voice.optional(),
timing: narrationTiming.optional(),
});
export const baseScene = z.object({
id: z.string(),
duration: z.number().gte(0.1),
background: background.optional(),
transition: transition.optional(),
narration: narration.optional(),
});
export const textStyle = z.object({
fontSize: z.number().int().gte(1).lte(2147483647),
color: z.string().regex(/^#[0-9A-Fa-f]{6}$/),
fontFamily: z.string(),
fontWeight: z.string().optional(),
textAlign: z
.union([z.literal("left"), z.literal("center"), z.literal("right")])
.optional(),
});
export const position = z.object({
x: z.union([
z.number().int().gte(-2147483648).lte(2147483647),
z.literal("center")
]),
y: z.union([
z.number().int().gte(-2147483648).lte(2147483647),
z.literal("center")
]),
});
export const textContent = z.object({
text: z.string(),
style: textStyle,
position: position,
});
export const textScene = baseScene.merge(z.object({
type: z.literal("text"),
content: textContent,
}));
export const generateImageSource = z.object({
type: z.literal("generate"),
prompt: z.string(),
style: z
.union([
z.literal("photorealistic"),
z.literal("illustration"),
z.literal("anime"),
z.literal("sketch")
])
.optional(),
aspectRatio: z.string().optional(),
seed: z.number().int().gte(-2147483648).lte(2147483647).optional(),
});
export const imageContent = z.object({
src: z.union([z.string(), generateImageSource]),
fit: z.union([z.literal("cover"), z.literal("contain"), z.literal("fill")]),
position: position,
});
export const imageScene = baseScene.merge(z.object({
type: z.literal("image"),
content: imageContent,
}));
export const videoTrim = z.object({
start: z.number().nonnegative(),
end: z.number().nonnegative(),
});
export const videoContent = z.object({
src: z.string(),
trim: videoTrim.optional(),
});
export const videoScene = baseScene.merge(z.object({
type: z.literal("video"),
content: videoContent,
}));
export const textLayer = z.object({
type: z.literal("text"),
content: textContent,
zIndex: z.number().int().nonnegative().lte(2147483647).optional(),
opacity: z.number().optional(),
});
export const imageLayer = z.object({
type: z.literal("image"),
content: imageContent,
zIndex: z.number().int().nonnegative().lte(2147483647).optional(),
opacity: z.number().optional(),
});
export const layer = z.union([textLayer, imageLayer]);
export const compositeScene = baseScene.merge(z.object({
type: z.literal("composite"),
layers: z.array(layer),
}));
export const scene = z.union([
textScene,
imageScene,
videoScene,
compositeScene
]);
export const weightedPrompt = z.object({
text: z.string(),
weight: z.number().nonnegative().lte(1),
});
export const musicGenerationConfig = z.object({
bpm: z.number().int().gte(60).lte(200).optional(),
temperature: z.number().nonnegative().lte(3).optional(),
guidance: z.number().nonnegative().lte(6).optional(),
density: z.number().nonnegative().lte(1).optional(),
brightness: z.number().nonnegative().lte(1).optional(),
scale: z.string().optional(),
muteBass: z.boolean().optional(),
muteDrums: z.boolean().optional(),
onlyBassAndDrums: z.boolean().optional(),
});
export const generateMusicSource = z.object({
type: z.literal("generate"),
prompts: z.array(weightedPrompt).optional(),
prompt: z.string().optional(),
config: musicGenerationConfig.optional(),
duration: z.number().optional(),
seed: z.number().int().gte(-2147483648).lte(2147483647).optional(),
});
export const backgroundMusic = z.object({
src: z.union([z.string(), generateMusicSource]),
volume: z.number().nonnegative().lte(1),
fadeIn: z.number().nonnegative().optional(),
fadeOut: z.number().nonnegative().optional(),
});
export const audioSettings = z.object({
backgroundMusic: backgroundMusic.optional(),
});
export const kumikiProject = z.object({
version: z.string(),
name: z.string(),
settings: projectSettings,
scenes: z.array(scene).min(1),
audio: audioSettings.optional(),
});
//# sourceMappingURL=models.js.map