Product Advertisement Video
Upload up to 3 reference images of your product A one click workflow to create a cinematic advertisement video of your product. Upload up to 3 images of your product, duration, number of unique cuts/shots, and add custom instructions (optional). An LLM processes all this and creates a structured prompt for MiniMax H3 to generate a consistent, on brand product video.
简介
This ComfyUI workflow builds a cinematic, multi-shot product advertisement video from up to three reference images. In the Inputs group, you supply Image 1 as the hero/environment reference (the scene this image defines is maintained across all shots) and use Images 2–3 for product detail references. Duration and number of unique shots are controlled with PrimitiveInt nodes, while optional brand/style guidance goes into a PrimitiveStringMultiline input. The LLM Prompt Generation group uses GeminiNodeV2 to transform your inputs into a single, time-cued prompt that MiniMax H3 understands (for example: 0–3s Shot 1, 3–6s Shot 2, etc.). The structured prompt, plus your references, then drives the MiniMax H3 node to render a consistent, on-brand video.
What makes this workflow especially efficient is its one-prompt multishot design. MiniMax H3 expects a single prompt containing all shots and their time windows, so the GeminiNodeV2 node formats a clean shot list with camera moves, transitions, and product highlights. You can preview and verify the shot script using PreviewAny and MarkdownNote. Once satisfied, paste the final script into the Edit Prompt? group to "lock" it and bypass the LLM step for fast, repeatable iterations. The Generate and Save Video group then renders the ad and writes it to disk via SaveVideo, giving you a repeatable pipeline for quickly producing consistent product spots.
你需要提供
- 正在读取工作流
在 ComfyUI 中运行。 此工作流无法在本页面运行。你可以在 Comfy Cloud 中打开(已预先加载所需内容),或下载后在自己的 ComfyUI 中使用。
在 Cloud 中试用查看工作流内部
节点图的只读预览。在 Comfy Cloud 中打开或下载后即可编辑节点。
Loading the graph
Open full-size workflow preview- 作者
- Rob
需要自定义节点
- 正在读取工作流
通过代码使用此工作流
尽可能根据工作流图和输入自动生成代码,否则显示已保存的示例。运行代码可能产生费用,请先核对凭据和端点。
What you need
- Runs on
- Comfy Cloud
- 密钥
- COMFY_API_KEY
需要付费的 Cloud 方案和额度。
# Python 3.10+: pip install comfy-sdk==0.4.0
import os
from comfy_sdk import Comfy
api_key = os.environ.get("COMFY_API_KEY", "").strip()
if not api_key: raise RuntimeError("Set COMFY_API_KEY")
os.environ.setdefault("COMFY_BASE_URL", "https://cloud.comfy.org")
client = Comfy(api_key=api_key)
workflow = client.workflows.from_json({
"4": {
"class_type": "LoadImage",
"inputs": {
"image": "c8696e8418db0e28c85df8c77d45ccead226c715bdef0a31829d27dbc882d999.png"
},
"_meta": {
"title": "Load Start Frame Image"
}
},
"8": {
"class_type": "LoadImage",
"inputs": {
"image": "13666a63b947d427aeb28f03fddfc28e268253f0c57346147525a32ebda49f8a.png"
},
"_meta": {
"title": "Load Product Image 1"
}
},
"12": {
"class_type": "LoadImage",
"inputs": {
"image": "554988911d94eb13700712629e48101e44456bc2bafb52cd8ca347a49cb25371.png"
},
"_meta": {
"title": "Load Product Image 2"
}
},
"22": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 10
},
"_meta": {
"title": "Total Seconds (4-15)"
}
},
"23": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 5
},
"_meta": {
"title": "Number of Shots"
}
},
"164": {
"class_type": "GeminiNodeV2",
"inputs": {
"model": "Gemini 3.1 Pro",
"model.images.image_1": [
"4",
0
],
"model.images.image_2": [
"8",
0
],
"model.images.image_3": [
"12",
0
],
"model.max_output_tokens": 32768,
"model.temperature": 1,
"model.thinking_level": "HIGH",
"model.top_p": 0.95,
"prompt": [
"81:85",
0
],
"seed": 111111,
"system_prompt": [
"309",
0
]
},
"_meta": {
"title": "Google Gemini"
}
},
"165": {
"class_type": "PrimitiveStringMultiline",
"inputs": {
"value": ""
},
"_meta": {
"title": "Prompt Input (copy/paste prompt here to make edits)"
}
},
"166": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"164",
0
]
},
"_meta": {
"title": "Preview Generated Prompt"
}
},
"200": {
"class_type": "PrimitiveStringMultiline",
"inputs": {
"value": ""
},
"_meta": {
"title": "User Story / Creative Direction (optional)"
}
},
"309": {
"class_type": "PrimitiveStringMultiline",
"inputs": {
"value": "You are a creative director and video prompt specialist for high-end product ads. Your job is to analyze the provided product reference images and write ONE complete multi-shot video prompt (a reference-to-video model), in the sleek, editorial style of luxury product advertising (think Aesop, Dior, etc.).\n\n---\n\n## INPUT\nYou will receive:\n- Reference images. <Picture 1> is the hero/environment reference — its scene, surface, lighting, and atmosphere are the locked environment for the entire film. Any additional images are product detail references (label, texture, materials).\n- {N_SHOTS}: the number of distinct shots (1-8)\n- {N_SECONDS}: the total video duration in seconds (5-15). This is a hard constraint.\n- {USER_STORY}: optional creative direction. If provided, it overrides or augments your inferred vibe. If empty, rely entirely on your image analysis.\n\n---\n\n## STEP 1 — ANALYZE THE IMAGES\nBefore writing anything, internally assess from <Picture 1> (cross-referencing detail images):\n- Product type, shape, color, material, and finish\n- Existing lighting mood (hard/soft, warm/cool, dramatic/flat)\n- Background environment — describe it precisely and literally: surface type, color, texture, depth, atmosphere. This becomes a locked constant for all shots.\n- Implied brand positioning (luxury, minimal, bold, clinical, artisanal, etc.)\n\n## STEP 2 — DEFINE THE STYLE FRAME\nDerive a set of locked style constants in the editorial product-film idiom:\n1. **One palette.** A single monochromatic or duotone color world derived from the product and <Picture 1> (e.g. warm amber on near-black; sepia charcoal; cool blue-black). Every shot lives inside it.\n2. **One light.** A single motivated key light with deep, soft shadow falloff — chiaroscuro, not flat e-commerce lighting. Light can move, bloom, or sweep; it never multiplies.\n3. **One environment.** The scene from image 1, held constant. Seamless backdrop or minimal studio void. Never introduce new rooms, floors, or locations.\n4. **One material motif.** A single tactile material drawn from the product's story (its ingredient, texture, or context — e.g. wood shavings, stone, water, leather, silk, metal filings). It may appear as a macro landscape, as suspended fragments, or as a surface the product rests on — but it is ONE motif, reused, not a new prop per shot.\n5. **Suspended physics.** Levitation, slow rotation, fragments frozen or drifting mid-air, ultra-slow-motion — deliberate, weightless, controlled.\n\n## STEP 3 — ASSIGN A SHOT SEQUENCE\nMap {N_SHOTS} to an ad narrative arc:\n\n| Shot Role | Purpose |\n|---------------|----------------------------------------------------------|\n| Hero (Shot 1) | Product reveal — slow, confident, emerging from darkness |\n| Detail | Extreme macro of texture, material, label, or motif |\n| Feature | Product interacting with the material motif or light |\n| Lifestyle | Product in a wider, styled composition of its world |\n| Outro | Pull back, final beauty angle, settle into stillness |\n\n- 1-2 shots: Hero + Outro only\n- 3 shots: Hero, Detail (or Feature), Outro\n- 4 shots: Hero, Detail, Feature, Outro\n- 5 shots: Hero, Detail, Feature, Lifestyle, Outro\n- 6 shots: Hero, Detail, Detail, Feature, Lifestyle, Outro\n\n## STEP 4 — ALLOCATE TIME\nSplit {N_SECONDS} across the shots as contiguous time segments starting at 0.0s:\n- Use increments of 0.5 seconds; segments must sum EXACTLY to {N_SECONDS}\n- No shot shorter than 1.0s\n- Luxury/cinematic vibe: favor a longer Hero and Outro, compress middle shots\n- Energetic/bold vibe: distribute evenly, keep every shot punchy\n\n## STEP 5 — WRITE THE PROMPT\nProduce one continuous prompt with this structure:\n1. An opening global-style paragraph: film type, the product (as \"the product from <Picture 1>\"), the locked palette, light, environment, and material motif, and the note that the environment from <Picture 1> is constant throughout.\n2. One time-cued line per shot in the form `SHOT # [start s - end s] - `, beginning every shot after the first with \"Cut to\". Describe: camera angle and motion, subject action, how the light behaves, and how the motif participates. 25-60 words per shot.\n3. A final `Audio:` line - minimal ambient bed, subtle whoosh on cuts, delicate foley tied to the material motif, and a restrained musical gesture that resolves on the last shot. No voiceover, no lyrics.\n\nPrompt writing rules:\n- Present tense, descriptive and directive; lead with the most important visual element of each shot\n- Ground identity in the references: say \"the product from <Picture 1>\"; when a detail matters, cite its source (e.g. \"the label exactly as in <Picture 2>\")\n- Shot 1 opens on (or quickly reveals) the composition of <Picture 1> before the camera begins to move\n- Vary angle, distance, and motion meaningfully between shots - at least one extreme macro when {N_SHOTS} >= 3\n- Camera vocabulary: slow push-in, glide, orbit, top-down descent, tilt reveal, drift back. One camera idea per shot.\n- No on-screen text, no logos, no titles, no graphics, no UI. No people unless {USER_STORY} asks for them.\n- The environment is a locked constant, not a creative variable. Never introduce new settings or weather.\n\n---\n\n## OUTPUT FORMAT\nOutput ONLY the final prompt text - no preamble, no explanation, no markdown fences, no quotes.\n\n---\n\n## EXAMPLES\nThese show the required structure, pacing, and quality bar. Do NOT copy their content - derive everything from the actual input images.\n\nExample (3 shots, 7 seconds, warm apothecary product):\n\nEditorial luxury product film. The dark amber glass bottle from <Picture 1> in its original scene: a matte near-black surface fading into a warm brown void, one warm spotlight from upper left, fine atmospheric haze, deep soft shadows. Monochromatic amber-on-black palette. Material motif: dried cedar shavings. The environment from image 1 is constant throughout.\nSHOT 1 [0.0s - 2.5s] - The scene opens exactly on <Picture 1>, the bottle standing centered in near-darkness; the spotlight slowly blooms brighter as the camera pushes in from a low angle; thin curls of cedar shaving drift weightlessly around the bottle.\nSHOT 2 [2.5s - 4.5s] - Cut to an extreme macro: the camera glides low across a backlit landscape of cedar shavings, shallow depth of field, warm rim light tracing every curled edge, the blurred silhouette of the bottle rising in the background.\nSHOT 3 [4.5s - 7.0s] - Cut to a slow orbit: the bottle levitates a few centimeters above the surface, rotating gently, shavings frozen mid-air around it; the light sweeps once across the glass, the camera drifts back, and everything settles into stillness.\nAudio: low warm room tone, a soft airy whoosh on each cut, delicate dry rustle of cedar shavings, a single swelling ambient chord that resolves to silence on the final settle.\n\nExample (4 shots, 10 seconds, matte black tech product):\n\nEditorial tech product film. The matte black over-ear headphones from <Picture 1> in their original scene: a charcoal studio void, one hard key light from camera right with long falloff, sepia-toned monochrome palette. Material motif: fine leather grain. The environment from <Picture 1> is constant throughout.\nSHOT 1 [0.0s - 3.0s] - The scene opens on <Picture 1> in heavy shadow; a blade of light sweeps slowly across the earcup, revealing the silhouette; the camera pushes in with almost imperceptible slowness.\nSHOT 2 [3.0s - 5.5s] - Cut to an extreme macro of the leather earpad grain from <Picture 2>, the texture rolling like dunes under raking sepia light, focus breathing gently across the stitching.\nSHOT 3 [5.5s - 8.0s] - Cut to an exploded view: the earcup components separate and float apart in ultra-slow motion, each part catching the key light in turn, suspended in the void.\nSHOT 4 [8.0s - 10.0s] - Cut to the fully assembled headphones levitating, a slow thirty-degree orbit as the parts settle home; the light dims until only the rim highlight remains.\nAudio: near-silent dark ambience, soft mechanical clicks as components separate and reseat, an airy whoosh on each cut, one low resonant synth swell that fades on the final rim light.\n\nExample (5 shots, 10 seconds, clear glass tech earbuds)\nEditorial tech film. The clear earbuds from <Picture 1> in an infinite black void. High-contrast monochrome palette with neon cyan accents. Stark studio light, sharp reflections. Material motif: glossy obsidian. Environment is a locked constant.\nSHOT 1 [0.0s - 2.5s] - The scene opens exactly on <Picture 1>. The clear case lid glides open. The earbuds rest in the white base as their blue rings ignite.\nSHOT 2 [2.5s - 4.5s] - Cut to extreme macro. Camera tracks down the transparent outer shell. The blue ring pulses brightly, casting a crisp cyan lens flare.\nSHOT 3 [4.5s - 6.5s] - Cut to slow push-in. The earbud levitates weightlessly toward the sleek, glossy black mannequin ear from <Picture 2>.\nSHOT 4 [6.5s - 8.0s] - Cut to tight profile. The earbud seats precisely into the ear. A vivid blue light pulse instantly washes down the glossy black neck.\nSHOT 5 [8.0s - 10.0s] - Cut to wide beauty orbit. Both earbuds levitate above the open case in the black void, pulsing in unison before the light fades.\nAudio: Deep room tone, sleek mechanical whoosh, a heavy digital bass pulse on connection, fading synth echo."
},
"_meta": {
"title": "System Prompt"
}
},
"327": {
"class_type": "SaveVideo",
"inputs": {
"filename_prefix": "video/MiniMax_H3",
"format": "auto",
"format.codec": "auto",
"video": [
"328:326",
0
]
},
"_meta": {
"title": "Save Video"
}
},
"115:111": {
"class_type": "ComfySwitchNode",
"inputs": {
"on_false": [
"165",
0
],
"on_true": [
"166",
0
],
"switch": [
"115:112",
0
]
},
"_meta": {
"title": "If/Else Switch"
}
},
"115:112": {
"class_type": "StringCompare",
"inputs": {
"case_sensitive": False,
"mode": "Equal",
"string_a": [
"165",
0
],
"string_b": [
"115:113",
0
]
},
"_meta": {
"title": "Compare Text"
}
},
"115:113": {
"class_type": "PrimitiveString",
"inputs": {
"value": ""
},
"_meta": {
"title": "Empty String"
}
},
"328:311": {
"class_type": "ComfyMathExpression",
"inputs": {
"expression": "max(5, round(a * 24)) + (5 - (max(5, round(a * 24)) % 17)) % 17",
"values.a": [
"22",
0
]
},
"_meta": {
"title": "Math Expression"
}
},
"328:313": {
"class_type": "ResolutionSelector",
"inputs": {
"aspect_ratio": "16:9 (Widescreen)",
"megapixels": 1,
"multiple": 32
},
"_meta": {
"title": "Resolution Selector (Size)"
}
},
"328:314": {
"class_type": "VAELoader",
"inputs": {
"vae_name": "minimax_h3_audio_vae_fp32.safetensors"
},
"_meta": {
"title": "Load VAE"
}
},
"328:315": {
"class_type": "MiniMaxH3ReferenceToVideo",
"inputs": {
"audio_vae": [
"328:314",
0
],
"clip": [
"328:317",
0
],
"height": [
"328:313",
1
],
"length": [
"328:311",
1
],
"prompt": [
"115:111",
0
],
"ref_image_size": "match",
"ref_images.ref_image_0": [
"4",
0
],
"ref_images.ref_image_1": [
"8",
0
],
"ref_images.ref_image_2": [
"12",
0
],
"vae": [
"328:316",
0
],
"width": [
"328:313",
0
]
},
"_meta": {
"title": "MiniMax H3 Reference to Video"
}
},
"328:316": {
"class_type": "VAELoader",
"inputs": {
"vae_name": "minimax_h3_video_vae_fp16.safetensors"
},
"_meta": {
"title": "Load VAE"
}
},
"328:317": {
"class_type": "CLIPLoader",
"inputs": {
"clip_name": "qwen3vl_32b_minimax_h3_int8_convrot.safetensors",
"device": "default",
"type": "minimax"
},
"_meta": {
"title": "Load CLIP"
}
},
"328:318": {
"class_type": "KSamplerSelect",
"inputs": {
"sampler_name": "res_multistep"
},
"_meta": {
"title": "KSamplerSelect"
}
},
"328:319": {
"class_type": "BasicScheduler",
"inputs": {
"denoise": 1,
"model": [
"328:321",
0
],
"scheduler": "simple",
"steps": 20
},
"_meta": {
"title": "BasicScheduler"
}
},
"328:320": {
"class_type": "BasicGuider",
"inputs": {
"conditioning": [
"328:315",
0
],
"model": [
"328:321",
0
]
},
"_meta": {
"title": "Basic Guider"
}
},
"328:321": {
"class_type": "UNETLoader",
"inputs": {
"unet_name": "minimax_h3_ref2va_pruned_int8_convrot.safetensors",
"weight_dtype": "default"
},
"_meta": {
"title": "Load Diffusion Model"
}
},
"328:322": {
"class_type": "RandomNoise",
"inputs": {
"noise_seed": 873821824241961
},
"_meta": {
"title": "RandomNoise"
}
},
"328:323": {
"class_type": "SamplerCustomAdvanced",
"inputs": {
"guider": [
"328:320",
0
],
"latent_image": [
"328:315",
1
],
"noise": [
"328:322",
0
],
"sampler": [
"328:318",
0
],
"sigmas": [
"328:319",
0
]
},
"_meta": {
"title": "SamplerCustomAdvanced"
}
},
"328:324": {
"class_type": "VAEDecodeAudio",
"inputs": {
"samples": [
"328:323",
0
],
"vae": [
"328:314",
0
]
},
"_meta": {
"title": "VAE Decode Audio"
}
},
"328:325": {
"class_type": "VAEDecode",
"inputs": {
"samples": [
"328:323",
0
],
"vae": [
"328:316",
0
]
},
"_meta": {
"title": "VAE Decode"
}
},
"328:326": {
"class_type": "CreateVideo",
"inputs": {
"audio": [
"328:324",
0
],
"bit_depth": 8,
"codec": "none",
"color_space": "sRGB",
"fps": 24,
"images": [
"328:325",
0
]
},
"_meta": {
"title": "Create Video"
}
},
"81:303": {
"class_type": "PrimitiveStringMultiline",
"inputs": {
"value": "Using the attached reference images (image 1 is the hero/environment reference; any additional images are product detail references), create one multi-shot video prompt with {N_SHOTS} distinct shots. The total video duration is exactly {N_SECONDS} seconds.\n\nCreative direction from the user (may be empty): {USER_STORY}"
},
"_meta": {
"title": "Template User Prompt"
}
},
"81:76": {
"class_type": "SomethingToString",
"inputs": {
"input": [
"23",
0
],
"prefix": "",
"suffix": ""
},
"_meta": {
"title": "Something To String"
}
},
"81:77": {
"class_type": "SomethingToString",
"inputs": {
"input": [
"22",
0
],
"prefix": "",
"suffix": ""
},
"_meta": {
"title": "Something To String"
}
},
"81:78": {
"class_type": "RegexReplace",
"inputs": {
"case_insensitive": True,
"count": 0,
"dotall": False,
"multiline": False,
"regex_pattern": "{N_SHOTS}",
"replace": [
"81:76",
0
],
"string": [
"81:303",
0
]
},
"_meta": {
"title": "Replace Text (Regex)"
}
},
"81:79": {
"class_type": "RegexReplace",
"inputs": {
"case_insensitive": True,
"count": 0,
"dotall": False,
"multiline": False,
"regex_pattern": "{N_SECONDS}",
"replace": [
"81:77",
0
],
"string": [
"81:78",
0
]
},
"_meta": {
"title": "Replace Text (Regex)"
}
},
"81:85": {
"class_type": "RegexReplace",
"inputs": {
"case_insensitive": True,
"count": 0,
"dotall": False,
"multiline": False,
"regex_pattern": "{USER_STORY}",
"replace": [
"200",
0
],
"string": [
"81:79",
0
]
},
"_meta": {
"title": "Replace Text (Regex)"
}
}
})
# run() also passes api_key to the partner nodes in this workflow.
job = client.run(workflow, api_key=api_key)常见问答
MiniMax H3 expects a single prompt that contains all shots with explicit time ranges (e.g., 0–3s, 3–6s). The GeminiNodeV2 builds this time-cued shot list so H3 can render multiple cuts from one structured prompt.
Use a strong, on-brand Image 1 as the hero/environment reference. The workflow locks its scene for every shot. Avoid instructions that drastically change locations mid-prompt if you want consistency.
Yes. The template supports up to three by default, but you can wire additional LoadImage nodes and feed them into the same prompt and generator inputs as needed.
GeminiNodeV2 and MiniMax H3 often call external services. Depending on your node configuration, you may need valid API keys and network access. Check each node’s settings and your ComfyUI console for requirements.