|
import Replicate from "replicate" |
|
|
|
import { generateSeed } from "@/lib/generateSeed" |
|
import { VideoOptions } from "@/types" |
|
import { sleep } from "@/lib/sleep" |
|
|
|
const replicateToken = `${process.env.AUTH_REPLICATE_API_TOKEN || ""}` |
|
const replicateModel = `${process.env.VIDEO_HOTSHOT_XL_API_REPLICATE_MODEL || ""}` |
|
const replicateModelVersion = `${process.env.VIDEO_HOTSHOT_XL_API_REPLICATE_MODEL_VERSION || ""}` |
|
|
|
export async function generateVideoWithReplicateAPI({ |
|
positivePrompt = "", |
|
negativePrompt = "", |
|
size = "512x512", |
|
huggingFaceLora, |
|
replicateLora, |
|
nbFrames = 8, |
|
duration = 1000, |
|
steps = 30, |
|
}: VideoOptions): Promise<string> { |
|
if (!replicateToken) { |
|
throw new Error(`you need to configure your AUTH_REPLICATE_API_TOKEN in order to use the REPLICATE rendering engine`) |
|
} |
|
if (!replicateModel) { |
|
throw new Error(`you need to configure your RENDERING_REPLICATE_API_MODEL in order to use the REPLICATE rendering engine`) |
|
} |
|
|
|
if (!replicateModelVersion) { |
|
throw new Error(`you need to configure your REPLICATE_API_MODEL_VERSION in order to use the REPLICATE rendering engine`) |
|
} |
|
const replicate = new Replicate({ auth: replicateToken }) |
|
|
|
const [width, height] = size.split("x").map(x => Number(x)) |
|
|
|
|
|
const seed = generateSeed() |
|
const prediction = await replicate.predictions.create({ |
|
version: replicateModelVersion, |
|
input: { |
|
prompt, |
|
negative_prompt: negativePrompt, |
|
|
|
|
|
hf_lora_url: replicateLora ? undefined : huggingFaceLora, |
|
|
|
|
|
replicate_weights_url: huggingFaceLora ? undefined : replicateLora, |
|
|
|
width, |
|
height, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
video_length: 8, |
|
video_duration: 1000, |
|
|
|
seed |
|
} |
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
await sleep(50000) |
|
|
|
try { |
|
const res = await fetch(`https://api.replicate.com/v1/predictions/${prediction.id}`, { |
|
method: "GET", |
|
headers: { |
|
Authorization: `Token ${replicateToken}`, |
|
}, |
|
cache: 'no-store', |
|
}) |
|
|
|
if (res.status !== 200) { |
|
throw new Error("failed") |
|
} |
|
|
|
const response = (await res.json()) as any |
|
const error = `${response?.error || ""}` |
|
if (error) { |
|
throw new Error(error) |
|
} |
|
return `${response?.output || ""}` |
|
} catch (err) { |
|
|
|
await sleep(10000) |
|
|
|
const res = await fetch(`https://api.replicate.com/v1/predictions/${prediction.id}`, { |
|
method: "GET", |
|
headers: { |
|
Authorization: `Token ${replicateToken}`, |
|
}, |
|
cache: 'no-store', |
|
|
|
|
|
}) |
|
|
|
if (res.status !== 200) { |
|
throw new Error('Failed to fetch data') |
|
} |
|
|
|
const response = (await res.json()) as any |
|
const error = `${response?.error || ""}` |
|
if (error) { |
|
throw new Error(error) |
|
} |
|
return `${response?.output || ""}` |
|
} |
|
} |