|
"use server" |
|
|
|
import { VideoOptions } from "@/types" |
|
|
|
import { generateVideoWithGradioAPI } from "./generateWithGradioApi" |
|
import { generateVideoWithReplicateAPI } from "./generateWithReplicateAPI" |
|
import { filterOutBadWords } from "./censorship" |
|
|
|
const videoEngine = `${process.env.VIDEO_ENGINE || ""}` |
|
|
|
|
|
const nodeApi = `${process.env.VIDEO_HOTSHOT_XL_API_NODE || ""}` |
|
|
|
export async function generateAnimation({ |
|
positivePrompt = "", |
|
negativePrompt = "", |
|
size = "512x512", |
|
huggingFaceLora, |
|
replicateLora, |
|
triggerWord, |
|
nbFrames = 8, |
|
duration = 1000, |
|
steps = 30, |
|
}: VideoOptions): Promise<string> { |
|
if (!positivePrompt?.length) { |
|
throw new Error(`prompt is too short!`) |
|
} |
|
|
|
positivePrompt = filterOutBadWords(positivePrompt) |
|
|
|
|
|
positivePrompt = [ |
|
triggerWord, |
|
positivePrompt, |
|
"beautiful", |
|
"hd" |
|
].join(", ") |
|
|
|
negativePrompt = [ |
|
negativePrompt, |
|
"cropped", |
|
"dark", |
|
"underexposed", |
|
"overexposed", |
|
"watermark", |
|
"watermarked", |
|
].join(", ") |
|
|
|
try { |
|
|
|
if (videoEngine === "VIDEO_HOTSHOT_XL_API_REPLICATE") { |
|
return generateVideoWithReplicateAPI({ |
|
positivePrompt, |
|
negativePrompt, |
|
size, |
|
huggingFaceLora, |
|
replicateLora, |
|
nbFrames, |
|
duration, |
|
steps, |
|
}) |
|
|
|
} else if (videoEngine === "VIDEO_HOTSHOT_XL_API_NODE") { |
|
|
|
|
|
const res = await fetch(nodeApi, { |
|
method: "POST", |
|
headers: { |
|
"Content-Type": "application/json", |
|
|
|
|
|
}, |
|
body: JSON.stringify({ |
|
prompt: positivePrompt, |
|
lora: huggingFaceLora, |
|
size, |
|
}), |
|
cache: "no-store", |
|
|
|
|
|
}) |
|
|
|
const content = await res.text() |
|
|
|
|
|
if (res.status !== 200) { |
|
console.error(content) |
|
|
|
throw new Error('Failed to fetch data') |
|
} |
|
|
|
return content |
|
} else if (videoEngine === "VIDEO_HOTSHOT_XL_API_GRADIO") { |
|
return generateVideoWithGradioAPI({ |
|
positivePrompt, |
|
negativePrompt, |
|
size, |
|
huggingFaceLora, |
|
replicateLora, |
|
nbFrames, |
|
duration, |
|
steps, |
|
}) |
|
} else { |
|
throw new Error(`not implemented yet!`) |
|
} |
|
|
|
} catch (err) { |
|
throw new Error(`failed to generate the image ${err}`) |
|
} |
|
} |