feat: Added support for Anime Style [WAN 2.2 I2V] #1
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,4 +1,5 @@
|
|||||||
AI Gen Code/
|
AI Gen Code/
|
||||||
|
Payload/
|
||||||
|
|
||||||
.env
|
.env
|
||||||
.env.*
|
.env.*
|
||||||
|
|||||||
@@ -222,6 +222,27 @@ async def _upload_asset_to_comfy(db: Session, asset_id: Optional[str]) -> Option
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _apply_model_preset(prompt: str, negative_prompt: str, model_preset: Optional[str]) -> tuple[str, str]:
|
||||||
|
if model_preset != "wan22-a14b-anime-style":
|
||||||
|
return prompt, negative_prompt
|
||||||
|
|
||||||
|
positive = prompt
|
||||||
|
negative = negative_prompt
|
||||||
|
|
||||||
|
if "An1meStyl3" not in positive:
|
||||||
|
positive = f"An1meStyl3, AnimeStyle, {positive}".strip(", ")
|
||||||
|
elif "AnimeStyle" not in positive:
|
||||||
|
positive = f"AnimeStyle, {positive}".strip(", ")
|
||||||
|
|
||||||
|
anime_negative = "(((realistic))), ((photograph))"
|
||||||
|
if "realistic" not in negative.lower():
|
||||||
|
negative = f"{negative}, {anime_negative}".strip(", ")
|
||||||
|
elif "photograph" not in negative.lower():
|
||||||
|
negative = f"{negative}, ((photograph))".strip(", ")
|
||||||
|
|
||||||
|
return positive, negative
|
||||||
|
|
||||||
|
|
||||||
def _validate_job(job: Job) -> list[str]:
|
def _validate_job(job: Job) -> list[str]:
|
||||||
errors = []
|
errors = []
|
||||||
if not job.prompt or not job.prompt.strip():
|
if not job.prompt or not job.prompt.strip():
|
||||||
@@ -265,18 +286,25 @@ async def run_job(job_id: str) -> None:
|
|||||||
ref_names.append(uploaded)
|
ref_names.append(uploaded)
|
||||||
|
|
||||||
settings_dict = json.loads(job.settings_json) if job.settings_json else {}
|
settings_dict = json.loads(job.settings_json) if job.settings_json else {}
|
||||||
binder = WorkflowBinder(select_template_name(job.mode, job.submode))
|
model_preset = settings_dict.get("model_preset")
|
||||||
|
template_name = select_template_name(job.mode, job.submode, model_preset)
|
||||||
|
binder = WorkflowBinder(template_name)
|
||||||
if "PLACEHOLDER" in binder.status.upper():
|
if "PLACEHOLDER" in binder.status.upper():
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
f"Workflow template '{select_template_name(job.mode, job.submode)}' is still a placeholder. "
|
f"Workflow template '{template_name}' is still a placeholder. "
|
||||||
"Replace it with the production ComfyUI export before running real generations."
|
"Replace it with the production ComfyUI export before running real generations."
|
||||||
)
|
)
|
||||||
raw_seed = settings_dict.get("seed", 0)
|
raw_seed = settings_dict.get("seed", 0)
|
||||||
seed = raw_seed if isinstance(raw_seed, int) and raw_seed >= 0 else 0
|
seed = raw_seed if isinstance(raw_seed, int) and raw_seed >= 0 else 0
|
||||||
|
positive_prompt, negative_prompt = _apply_model_preset(
|
||||||
|
job.prompt,
|
||||||
|
job.negative_prompt or "",
|
||||||
|
model_preset,
|
||||||
|
)
|
||||||
|
|
||||||
params = {
|
params = {
|
||||||
"positive_prompt": job.prompt,
|
"positive_prompt": positive_prompt,
|
||||||
"negative_prompt": job.negative_prompt or "",
|
"negative_prompt": negative_prompt,
|
||||||
"ground_truth": gt_name,
|
"ground_truth": gt_name,
|
||||||
"motion_video": motion_name,
|
"motion_video": motion_name,
|
||||||
"audio": audio_name,
|
"audio": audio_name,
|
||||||
@@ -288,7 +316,7 @@ async def run_job(job_id: str) -> None:
|
|||||||
}
|
}
|
||||||
workflow = binder.bind(params)
|
workflow = binder.bind(params)
|
||||||
await _validate_runtime_models(workflow)
|
await _validate_runtime_models(workflow)
|
||||||
job.workflow_template_name = select_template_name(job.mode, job.submode)
|
job.workflow_template_name = template_name
|
||||||
job.workflow_template_version = binder.version
|
job.workflow_template_version = binder.version
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
|
|||||||
@@ -25,8 +25,12 @@ def _discover() -> None:
|
|||||||
_discover()
|
_discover()
|
||||||
|
|
||||||
|
|
||||||
def select_template_name(mode: str, submode: Optional[str]) -> str:
|
def select_template_name(mode: str, submode: Optional[str], model_preset: Optional[str] = None) -> str:
|
||||||
if mode == "animate":
|
if mode == "animate":
|
||||||
|
if model_preset == "wan22-a14b-anime-style":
|
||||||
|
if (submode or "move") != "move":
|
||||||
|
raise ValueError("Anime Style preset is currently supported only for Animate / Move.")
|
||||||
|
return "wan22_animate_move_anime_style"
|
||||||
return f"wan22_animate_{submode or 'move'}"
|
return f"wan22_animate_{submode or 'move'}"
|
||||||
if mode == "audio":
|
if mode == "audio":
|
||||||
return "wan22_s2v"
|
return "wan22_s2v"
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ type ComposerState = {
|
|||||||
aspectPreset: "16:9" | "1:1" | "9:16";
|
aspectPreset: "16:9" | "1:1" | "9:16";
|
||||||
durationPreset: "5s" | "8s";
|
durationPreset: "5s" | "8s";
|
||||||
generationCount: 1 | 2 | 3 | 4;
|
generationCount: 1 | 2 | 3 | 4;
|
||||||
modelPreset: "wan22-a14b";
|
modelPreset: "wan22-a14b" | "wan22-a14b-anime-style";
|
||||||
};
|
};
|
||||||
|
|
||||||
type AssetKind = "image" | "video" | "audio" | "pose_sheet";
|
type AssetKind = "image" | "video" | "audio" | "pose_sheet";
|
||||||
@@ -428,19 +428,19 @@ export function DashboardClient() {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
{outputMenuOpen ? (
|
{outputMenuOpen ? (
|
||||||
<div className="absolute bottom-[4.75rem] right-5 z-20 w-full max-w-md rounded-[26px] border border-white/10 bg-[rgba(12,16,23,0.98)] p-4 shadow-glow backdrop-blur-xl sm:right-6">
|
<div className="fixed right-4 top-6 z-30 w-[min(24rem,calc(100vw-2rem))] max-h-[min(34rem,calc(100vh-3rem))] overflow-y-auto rounded-[24px] border border-white/10 bg-[rgba(12,16,23,0.98)] p-3.5 shadow-glow backdrop-blur-xl sm:right-6 sm:top-8">
|
||||||
<div className="mb-3 flex items-center justify-between gap-3">
|
<div className="mb-2.5 flex items-center justify-between gap-3">
|
||||||
<div className="text-xs uppercase tracking-[0.24em] text-subtext">Controls</div>
|
<div className="text-xs uppercase tracking-[0.24em] text-subtext">Controls</div>
|
||||||
<button
|
<button
|
||||||
className="flex h-9 w-9 items-center justify-center rounded-full border border-white/10 bg-white/[0.04] text-subtext transition hover:bg-white/[0.08] hover:text-white"
|
className="flex h-8 w-8 items-center justify-center rounded-full border border-white/10 bg-white/[0.04] text-subtext transition hover:bg-white/[0.08] hover:text-white"
|
||||||
onClick={() => setOutputMenuOpen(false)}
|
onClick={() => setOutputMenuOpen(false)}
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<X className="h-4 w-4" />
|
<X className="h-4 w-4" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid gap-3">
|
<div className="grid gap-2.5">
|
||||||
<div className="grid grid-cols-2 gap-2">
|
<div className="grid grid-cols-2 gap-1.5">
|
||||||
<button
|
<button
|
||||||
className={composer.mode === "animate" ? "btn-primary" : "btn-secondary"}
|
className={composer.mode === "animate" ? "btn-primary" : "btn-secondary"}
|
||||||
onClick={() => setComposer((current) => ({ ...current, mode: "animate" }))}
|
onClick={() => setComposer((current) => ({ ...current, mode: "animate" }))}
|
||||||
@@ -451,7 +451,7 @@ export function DashboardClient() {
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className={composer.mode === "audio" ? "btn-primary" : "btn-secondary"}
|
className={composer.mode === "audio" ? "btn-primary" : "btn-secondary"}
|
||||||
onClick={() => setComposer((current) => ({ ...current, mode: "audio" }))}
|
onClick={() => setComposer((current) => ({ ...current, mode: "audio", modelPreset: "wan22-a14b" }))}
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<Mic2 className="mr-2 h-4 w-4" />
|
<Mic2 className="mr-2 h-4 w-4" />
|
||||||
@@ -459,7 +459,7 @@ export function DashboardClient() {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-2 gap-2">
|
<div className="grid grid-cols-2 gap-1.5">
|
||||||
<button
|
<button
|
||||||
className={composer.activeSurface === "frames" ? "btn-primary" : "btn-secondary"}
|
className={composer.activeSurface === "frames" ? "btn-primary" : "btn-secondary"}
|
||||||
onClick={() => setComposer((current) => ({ ...current, activeSurface: "frames" }))}
|
onClick={() => setComposer((current) => ({ ...current, activeSurface: "frames" }))}
|
||||||
@@ -476,7 +476,7 @@ export function DashboardClient() {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-2 gap-2">
|
<div className="grid grid-cols-2 gap-1.5">
|
||||||
{composer.mode === "animate" ? (
|
{composer.mode === "animate" ? (
|
||||||
<>
|
<>
|
||||||
<button
|
<button
|
||||||
@@ -488,7 +488,7 @@ export function DashboardClient() {
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className={composer.submode === "mix" ? "btn-primary" : "btn-secondary"}
|
className={composer.submode === "mix" ? "btn-primary" : "btn-secondary"}
|
||||||
onClick={() => setComposer((current) => ({ ...current, submode: "mix" }))}
|
onClick={() => setComposer((current) => ({ ...current, submode: "mix", modelPreset: "wan22-a14b" }))}
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
Mix
|
Mix
|
||||||
@@ -501,7 +501,7 @@ export function DashboardClient() {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-2 gap-2">
|
<div className="grid grid-cols-2 gap-1.5">
|
||||||
{(["9:16", "16:9"] as const).map((key) => (
|
{(["9:16", "16:9"] as const).map((key) => (
|
||||||
<button
|
<button
|
||||||
className={composer.aspectPreset === key ? "btn-primary" : "btn-secondary"}
|
className={composer.aspectPreset === key ? "btn-primary" : "btn-secondary"}
|
||||||
@@ -514,7 +514,7 @@ export function DashboardClient() {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-2 gap-2">
|
<div className="grid grid-cols-2 gap-1.5">
|
||||||
{(["5s", "8s"] as const).map((key) => (
|
{(["5s", "8s"] as const).map((key) => (
|
||||||
<button
|
<button
|
||||||
className={composer.durationPreset === key ? "btn-primary" : "btn-secondary"}
|
className={composer.durationPreset === key ? "btn-primary" : "btn-secondary"}
|
||||||
@@ -527,7 +527,7 @@ export function DashboardClient() {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-4 gap-2">
|
<div className="grid grid-cols-4 gap-1.5">
|
||||||
{[1, 2, 3, 4].map((count) => (
|
{[1, 2, 3, 4].map((count) => (
|
||||||
<button
|
<button
|
||||||
className={composer.generationCount === count ? "btn-primary" : "btn-secondary"}
|
className={composer.generationCount === count ? "btn-primary" : "btn-secondary"}
|
||||||
@@ -545,13 +545,32 @@ export function DashboardClient() {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="rounded-[18px] border border-white/10 bg-white/[0.04] px-4 py-3 text-sm text-white">
|
<div className="grid gap-1.5">
|
||||||
Wan 2.2 A14B
|
<button
|
||||||
<div className="mt-1 text-xs text-subtext">More Coming Soon...</div>
|
className={composer.modelPreset === "wan22-a14b" ? "btn-primary" : "btn-secondary"}
|
||||||
|
onClick={() => setComposer((current) => ({ ...current, modelPreset: "wan22-a14b" }))}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
Wan 2.2 A14B Base
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className={composer.modelPreset === "wan22-a14b-anime-style" ? "btn-primary" : "btn-secondary"}
|
||||||
|
onClick={() =>
|
||||||
|
setComposer((current) => ({
|
||||||
|
...current,
|
||||||
|
mode: "animate",
|
||||||
|
submode: "move",
|
||||||
|
modelPreset: "wan22-a14b-anime-style",
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
Anime Style [WAN 2.2 I2V]
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="text-center text-xs leading-5 text-subtext">
|
<div className="px-1 text-center text-[11px] leading-5 text-subtext">
|
||||||
Start frame is live. End frame is planned. Batch `x1-x4` submits real jobs against the live queue.
|
Start frame is live. End frame is planned. Batch x1-x4 submits real jobs against the live queue.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
256
workflows/animate/wan22_animate_move_anime_style_v1.json
Normal file
256
workflows/animate/wan22_animate_move_anime_style_v1.json
Normal file
@@ -0,0 +1,256 @@
|
|||||||
|
{
|
||||||
|
"__animatrix_meta__": {
|
||||||
|
"name": "wan22_animate_move_anime_style",
|
||||||
|
"version": "1",
|
||||||
|
"model": "Wan2.2 I2V A14B Local Native + Anime Style v2 LoRAs",
|
||||||
|
"description": "Official local Comfy-native Wan 2.2 image-to-video runtime with Anime Style v2 LoRAs applied on both high-noise and low-noise stages.",
|
||||||
|
"param_nodes": {
|
||||||
|
"positive_prompt": { "node_id": "2", "input": "text" },
|
||||||
|
"negative_prompt": { "node_id": "3", "input": "text" },
|
||||||
|
"ground_truth": { "node_id": "1", "input": "image" },
|
||||||
|
"seed": { "node_id": "13", "input": "noise_seed" },
|
||||||
|
"width": { "node_id": "12", "input": "width" },
|
||||||
|
"height": { "node_id": "12", "input": "height" },
|
||||||
|
"length": { "node_id": "12", "input": "length" }
|
||||||
|
},
|
||||||
|
"status": "production_local_native_graph"
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"class_type": "LoadImage",
|
||||||
|
"inputs": {
|
||||||
|
"image": "ground_truth.png"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"class_type": "CLIPTextEncode",
|
||||||
|
"inputs": {
|
||||||
|
"text": "An1meStyl3, AnimeStyle, cinematic character animation from a grounded first frame",
|
||||||
|
"clip": [
|
||||||
|
"4",
|
||||||
|
0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
|
"class_type": "CLIPTextEncode",
|
||||||
|
"inputs": {
|
||||||
|
"text": "oversaturated, overexposed, static frame, blurry details, unclear details, watermark, messy background, low quality, jpeg artifacts, deformed limbs, extra fingers, ugly, distorted face, character drift, (((realistic))), ((photograph))",
|
||||||
|
"clip": [
|
||||||
|
"4",
|
||||||
|
0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"4": {
|
||||||
|
"class_type": "CLIPLoader",
|
||||||
|
"inputs": {
|
||||||
|
"clip_name": "umt5_xxl_fp8_e4m3fn_scaled.safetensors",
|
||||||
|
"type": "wan",
|
||||||
|
"device": "default"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"5": {
|
||||||
|
"class_type": "VAELoader",
|
||||||
|
"inputs": {
|
||||||
|
"vae_name": "wan_2.1_vae.safetensors"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"6": {
|
||||||
|
"class_type": "UNETLoader",
|
||||||
|
"inputs": {
|
||||||
|
"unet_name": "wan2.2_i2v_high_noise_14B_fp8_scaled.safetensors",
|
||||||
|
"weight_dtype": "default"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"7": {
|
||||||
|
"class_type": "UNETLoader",
|
||||||
|
"inputs": {
|
||||||
|
"unet_name": "wan2.2_i2v_low_noise_14B_fp8_scaled.safetensors",
|
||||||
|
"weight_dtype": "default"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"8": {
|
||||||
|
"class_type": "LoraLoaderModelOnly",
|
||||||
|
"inputs": {
|
||||||
|
"model": [
|
||||||
|
"6",
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"lora_name": "wan2.2_i2v_lightx2v_4steps_lora_v1_high_noise.safetensors",
|
||||||
|
"strength_model": 1.0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"9": {
|
||||||
|
"class_type": "LoraLoaderModelOnly",
|
||||||
|
"inputs": {
|
||||||
|
"model": [
|
||||||
|
"7",
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"lora_name": "wan2.2_i2v_lightx2v_4steps_lora_v1_low_noise.safetensors",
|
||||||
|
"strength_model": 1.0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"10": {
|
||||||
|
"class_type": "LoraLoaderModelOnly",
|
||||||
|
"inputs": {
|
||||||
|
"model": [
|
||||||
|
"8",
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"lora_name": "wan2.2_i2v_animestyle_v2_high.safetensors",
|
||||||
|
"strength_model": 1.0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"11": {
|
||||||
|
"class_type": "LoraLoaderModelOnly",
|
||||||
|
"inputs": {
|
||||||
|
"model": [
|
||||||
|
"9",
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"lora_name": "wan2.2_i2v_animestyle_v2_low.safetensors",
|
||||||
|
"strength_model": 1.0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"12": {
|
||||||
|
"class_type": "ModelSamplingSD3",
|
||||||
|
"inputs": {
|
||||||
|
"model": [
|
||||||
|
"10",
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"shift": 5.0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"13": {
|
||||||
|
"class_type": "WanImageToVideo",
|
||||||
|
"inputs": {
|
||||||
|
"positive": [
|
||||||
|
"2",
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"negative": [
|
||||||
|
"3",
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"vae": [
|
||||||
|
"5",
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"width": 832,
|
||||||
|
"height": 468,
|
||||||
|
"length": 81,
|
||||||
|
"batch_size": 1,
|
||||||
|
"start_image": [
|
||||||
|
"1",
|
||||||
|
0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"14": {
|
||||||
|
"class_type": "KSamplerAdvanced",
|
||||||
|
"inputs": {
|
||||||
|
"model": [
|
||||||
|
"12",
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"add_noise": "enable",
|
||||||
|
"noise_seed": 42,
|
||||||
|
"steps": 4,
|
||||||
|
"cfg": 1.0,
|
||||||
|
"sampler_name": "euler",
|
||||||
|
"scheduler": "simple",
|
||||||
|
"positive": [
|
||||||
|
"13",
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"negative": [
|
||||||
|
"13",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"latent_image": [
|
||||||
|
"13",
|
||||||
|
2
|
||||||
|
],
|
||||||
|
"start_at_step": 0,
|
||||||
|
"end_at_step": 2,
|
||||||
|
"return_with_leftover_noise": "enable"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"15": {
|
||||||
|
"class_type": "ModelSamplingSD3",
|
||||||
|
"inputs": {
|
||||||
|
"model": [
|
||||||
|
"11",
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"shift": 5.0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"16": {
|
||||||
|
"class_type": "KSamplerAdvanced",
|
||||||
|
"inputs": {
|
||||||
|
"model": [
|
||||||
|
"15",
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"add_noise": "disable",
|
||||||
|
"noise_seed": 42,
|
||||||
|
"steps": 4,
|
||||||
|
"cfg": 1.0,
|
||||||
|
"sampler_name": "euler",
|
||||||
|
"scheduler": "simple",
|
||||||
|
"positive": [
|
||||||
|
"13",
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"negative": [
|
||||||
|
"13",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"latent_image": [
|
||||||
|
"14",
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"start_at_step": 2,
|
||||||
|
"end_at_step": 4,
|
||||||
|
"return_with_leftover_noise": "disable"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"17": {
|
||||||
|
"class_type": "VAEDecode",
|
||||||
|
"inputs": {
|
||||||
|
"samples": [
|
||||||
|
"16",
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"vae": [
|
||||||
|
"5",
|
||||||
|
0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"18": {
|
||||||
|
"class_type": "CreateVideo",
|
||||||
|
"inputs": {
|
||||||
|
"images": [
|
||||||
|
"17",
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"fps": 16
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"19": {
|
||||||
|
"class_type": "SaveVideo",
|
||||||
|
"inputs": {
|
||||||
|
"video": [
|
||||||
|
"18",
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"filename_prefix": "AnimatrixAnimeStyle",
|
||||||
|
"format": "mp4",
|
||||||
|
"codec": "h264"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user