Kling 3.0: 1 Click Multishot
Upload a start frame and references of your product. Select total duration and number of shots and automatically generate prompts for each shot.
概要
The 'Kling 3.0: 1 Click Multishot' workflow is designed to streamline the process of creating dynamic video content from static images. By leveraging the Kling 3.0 model, this workflow allows users to upload a starting frame along with reference images of a product, then automatically generates a series of prompts for each shot based on the specified duration and number of shots.
The workflow utilizes several specialized nodes, including the KlingOmniProImageToVideoNode for transforming images into video sequences and the comfyui-string-converter for managing prompt data. This setup is particularly useful for content creators and marketers looking to produce engaging video content quickly and efficiently, without the need for extensive manual input.
入力するもの
- ワークフローを読み込み中
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": "comfy_gpu_angled.png"
},
"_meta": {
"title": "Load Start Frame Image"
}
},
"8": {
"class_type": "LoadImage",
"inputs": {
"image": "comfy_gpu_flat.png"
},
"_meta": {
"title": "Load Product Image 1"
}
},
"12": {
"class_type": "LoadImage",
"inputs": {
"image": "comfy_gpu_close_up.png"
},
"_meta": {
"title": "Load Product Image 2"
}
},
"22": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 8
},
"_meta": {
"title": "Number of Seconds (3-15)"
}
},
"23": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 2
},
"_meta": {
"title": "Number of Shots (1-6)"
}
},
"32": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"91:31",
0
]
},
"_meta": {
"title": "Shot 1: Prompt"
}
},
"35": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"91:36",
0
]
},
"_meta": {
"title": "Shot 1: # of Seconds"
}
},
"37": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"91:39",
0
]
},
"_meta": {
"title": "Shot 2: Prompt"
}
},
"38": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"91:40",
0
]
},
"_meta": {
"title": "Shot 2: # of Seconds"
}
},
"46": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"91:49",
0
]
},
"_meta": {
"title": "Shot 3: Prompt"
}
},
"47": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"91:48",
0
]
},
"_meta": {
"title": "Shot 3: # of Seconds"
}
},
"52": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"91:62",
0
]
},
"_meta": {
"title": "Shot 4: # of Seconds"
}
},
"53": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"91:60",
0
]
},
"_meta": {
"title": "Shot 5: Prompt"
}
},
"54": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"91:55",
0
]
},
"_meta": {
"title": "Shot 5: # of Seconds"
}
},
"57": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"91:58",
0
]
},
"_meta": {
"title": "Shot 6: # of Seconds"
}
},
"136": {
"class_type": "StringToInt",
"inputs": {
"data": [
"91:36",
0
]
},
"_meta": {
"title": "Shot 1: Duration"
}
},
"137": {
"class_type": "StringToInt",
"inputs": {
"data": [
"91:40",
0
]
},
"_meta": {
"title": "Shot 2: Duration"
}
},
"138": {
"class_type": "StringToInt",
"inputs": {
"data": [
"91:48",
0
]
},
"_meta": {
"title": "Shot 3: Duration"
}
},
"139": {
"class_type": "StringToInt",
"inputs": {
"data": [
"91:58",
0
]
},
"_meta": {
"title": "Shot 6: Duration"
}
},
"140": {
"class_type": "StringToInt",
"inputs": {
"data": [
"91:62",
0
]
},
"_meta": {
"title": "Shot 4: Duration"
}
},
"141": {
"class_type": "StringToInt",
"inputs": {
"data": [
"91:55",
0
]
},
"_meta": {
"title": "Shot 5: Duration"
}
},
"145": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"91:59",
0
]
},
"_meta": {
"title": "Shot 4: Prompt"
}
},
"148": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"91:61",
0
]
},
"_meta": {
"title": "Shot 6: Prompt"
}
},
"149": {
"class_type": "PrimitiveStringMultiline",
"inputs": {
"value": "You are a creative director and video prompt specialist. Your job is to analyze a product image and generate a sequence of cinematic video prompts for a multi-shot product advertisement.\n\n---\n\n## INPUT\nYou will receive:\n- A product image (used as the visual start frame for Shot 1 only)\n- {N_SHOTS}: the number of shots to generate (1–6)\n- {N_SECONDS}: the total cumulative duration across all shots (max 15 seconds)\n- {USER_STORY}: optional creative direction for vibe, narrative, or tone\n\n---\n\n## STEP 1 — ANALYZE THE IMAGE\nBefore writing any prompts, internally assess the following from the product image:\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, atmospheric elements (e.g. \"matte dark grey surface, no visible background, soft overhead diffusion\"). This description becomes a locked constant for all shots.\n- Implied brand positioning (luxury, minimal, bold, playful, clinical, etc.)\n\nIf {USER_STORY} is provided, let it override or augment your inferred vibe. If it is empty, rely entirely on your image analysis.\n\n---\n\n## STEP 2 — ASSIGN A SHOT SEQUENCE\nMap {N_SHOTS} to a logical ad narrative arc. Use this as your guide:\n\n| Shot Role | Purpose |\n|---------------|------------------------------------------------------|\n| Hero (Shot 1) | Product reveal — slow, confident, visually grounding |\n| Detail | Extreme close-up of texture, material, or finish |\n| Feature | Product in action, reacting to environment or use |\n| Lifestyle | Product in its natural world or context |\n| Outro | Pull back, final beauty angle, or ambient close |\n\nCompress or expand the arc based on shot count:\n- 1–2 shots: Hero + Outro only\n- 3 shots: Hero, 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---\n\n## STEP 3 — ALLOCATE DURATIONS\nDistribute seconds across shots. Rules:\n- All durations must be integers (whole seconds)\n- Total must equal exactly {N_SECONDS}\n- Weight durations by shot role and inferred pacing:\n - Luxury/cinematic vibe: favor longer Hero and Outro, compress middle shots\n - Energetic/bold vibe: distribute more evenly, keep all shots punchy\n - Default weighting: Hero gets ~25%, Outro gets ~20%, remaining shots split the rest\n\n---\n\n## STEP 4 — WRITE THE PROMPTS\n\n**Shot 1 (I2V — Image to Video):**\nThe product image is the literal start frame. Write a prompt that describes the motion and camera behavior starting from that exact frame. Do not re-describe the product appearance — describe only what moves and how.\n\n**Shots 2–N (T2V — Text to Video):**\nEach prompt must be fully self-contained. Describe the product, the scene, the camera, and the motion clearly enough that a video model with no prior context can generate a coherent, on-brand clip. You must preserve the exact environment from the input image — the same surface, background, depth, and atmosphere. Do not introduce new environments, floors, settings, or atmospheric elements (mist, smoke, reflections, etc.) that were not present in the input image. The environment is a locked constant, not a creative variable.\n\n**Prompt writing rules (apply to all shots):**\n- Write in present tense, descriptive and directive\n- Lead with the most important visual element\n- Specify: camera angle, camera motion, subject action, lighting, mood\n- Keep each prompt between 40–80 words — specific but not overloaded\n- No marketing copy, no voiceover text, no titles or graphics\n- Each shot must feel visually distinct from the others — vary angle, distance, and motion meaningfully\n\n---\n\n## OUTPUT FORMAT\nOutput only the tagged shot blocks. No preamble, no explanation, no additional text.\n\n<shot1_duration>N</shot1_duration>\n<shot1_prompt>Prompt text here</shot1_prompt>\n\n<shot2_duration>N</shot2_duration>\n<shot2_prompt>Prompt text here</shot2_prompt>\n\n...and so on for all {N_SHOTS} shots."
},
"_meta": {
"title": "System Prompt"
}
},
"164": {
"class_type": "GeminiNode",
"inputs": {
"images": [
"4",
0
],
"model": "gemini-3-pro-preview",
"prompt": [
"81:79",
0
],
"seed": 11185935742735,
"system_prompt": [
"149",
0
]
},
"_meta": {
"title": "Google Gemini"
}
},
"165": {
"class_type": "PrimitiveStringMultiline",
"inputs": {
"value": ""
},
"_meta": {
"title": "Prompt Input (copy/paste prompt here to lock)"
}
},
"166": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"164",
0
]
},
"_meta": {
"title": "Preview All Prompts"
}
},
"110:14": {
"class_type": "GetImageSize",
"inputs": {
"image": [
"4",
0
]
},
"_meta": {
"title": "Get Image Size"
}
},
"110:15": {
"class_type": "ResizeAndPadImage",
"inputs": {
"image": [
"8",
0
],
"interpolation": "area",
"padding_color": "white",
"target_height": [
"110:14",
1
],
"target_width": [
"110:14",
0
]
},
"_meta": {
"title": "Resize And Pad Image"
}
},
"110:16": {
"class_type": "ResizeAndPadImage",
"inputs": {
"image": [
"12",
0
],
"interpolation": "area",
"padding_color": "white",
"target_height": [
"110:14",
1
],
"target_width": [
"110:14",
0
]
},
"_meta": {
"title": "Resize And Pad Image"
}
},
"110:6": {
"class_type": "BatchImagesNode",
"inputs": {
"images.image0": [
"4",
0
],
"images.image1": [
"110:15",
0
],
"images.image2": [
"110:16",
0
]
},
"_meta": {
"title": "Batch Images"
}
},
"115:111": {
"class_type": "ComfySwitchNode",
"inputs": {
"on_false": [
"165",
0
],
"on_true": [
"164",
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"
}
},
"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:80",
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:80": {
"class_type": "Text Multiline",
"inputs": {
"text": "Use the input image 1, create a prompt that has N_SHOTS distinct shots. The total time for the shots is N_SECONDS. \n\nUSER_STORY."
},
"_meta": {
"title": "Template User Prompt"
}
},
"91:31": {
"class_type": "RegexExtract",
"inputs": {
"case_insensitive": True,
"dotall": False,
"group_index": 1,
"mode": "First Group",
"multiline": True,
"regex_pattern": "<shot1_prompt>(.+)</shot1_prompt>",
"string": [
"115:111",
0
]
},
"_meta": {
"title": "Extract Text"
}
},
"91:36": {
"class_type": "RegexExtract",
"inputs": {
"case_insensitive": True,
"dotall": False,
"group_index": 1,
"mode": "First Group",
"multiline": True,
"regex_pattern": "<shot1_duration>(\\d+)</shot1_duration>",
"string": [
"115:111",
0
]
},
"_meta": {
"title": "Extract Text"
}
},
"91:39": {
"class_type": "RegexExtract",
"inputs": {
"case_insensitive": True,
"dotall": False,
"group_index": 1,
"mode": "First Group",
"multiline": True,
"regex_pattern": "<shot2_prompt>(.+)</shot2_prompt>",
"string": [
"115:111",
0
]
},
"_meta": {
"title": "Extract Text"
}
},
"91:40": {
"class_type": "RegexExtract",
"inputs": {
"case_insensitive": True,
"dotall": False,
"group_index": 1,
"mode": "First Group",
"multiline": True,
"regex_pattern": "<shot2_duration>(\\d+)</shot2_duration>",
"string": [
"115:111",
0
]
},
"_meta": {
"title": "Extract Text"
}
},
"91:48": {
"class_type": "RegexExtract",
"inputs": {
"case_insensitive": True,
"dotall": False,
"group_index": 1,
"mode": "First Group",
"multiline": True,
"regex_pattern": "<shot3_duration>(\\d+)</shot3_duration>",
"string": [
"115:111",
0
]
},
"_meta": {
"title": "Extract Text"
}
},
"91:49": {
"class_type": "RegexExtract",
"inputs": {
"case_insensitive": True,
"dotall": False,
"group_index": 1,
"mode": "First Group",
"multiline": True,
"regex_pattern": "<shot3_prompt>(.+)</shot3_prompt>",
"string": [
"115:111",
0
]
},
"_meta": {
"title": "Extract Text"
}
},
"91:55": {
"class_type": "RegexExtract",
"inputs": {
"case_insensitive": True,
"dotall": False,
"group_index": 1,
"mode": "First Group",
"multiline": True,
"regex_pattern": "<shot5_duration>(\\d+)</shot5_duration>",
"string": [
"115:111",
0
]
},
"_meta": {
"title": "Extract Text"
}
},
"91:58": {
"class_type": "RegexExtract",
"inputs": {
"case_insensitive": True,
"dotall": False,
"group_index": 1,
"mode": "First Group",
"multiline": True,
"regex_pattern": "<shot6_duration>(\\d+)</shot6_duration>",
"string": [
"115:111",
0
]
},
"_meta": {
"title": "Extract Text"
}
},
"91:59": {
"class_type": "RegexExtract",
"inputs": {
"case_insensitive": True,
"dotall": False,
"group_index": 1,
"mode": "First Group",
"multiline": True,
"regex_pattern": "<shot4_prompt>(.+)</shot4_prompt>",
"string": [
"115:111",
0
]
},
"_meta": {
"title": "Extract Text"
}
},
"91:60": {
"class_type": "RegexExtract",
"inputs": {
"case_insensitive": True,
"dotall": False,
"group_index": 1,
"mode": "First Group",
"multiline": True,
"regex_pattern": "<shot5_prompt>(.+)</shot5_prompt>",
"string": [
"115:111",
0
]
},
"_meta": {
"title": "Extract Text"
}
},
"91:61": {
"class_type": "RegexExtract",
"inputs": {
"case_insensitive": True,
"dotall": False,
"group_index": 1,
"mode": "First Group",
"multiline": True,
"regex_pattern": "<shot6_prompt>(.+)</shot6_prompt>",
"string": [
"115:111",
0
]
},
"_meta": {
"title": "Extract Text"
}
},
"91:62": {
"class_type": "RegexExtract",
"inputs": {
"case_insensitive": True,
"dotall": False,
"group_index": 1,
"mode": "First Group",
"multiline": True,
"regex_pattern": "<shot4_duration>(\\d+)</shot4_duration>",
"string": [
"115:111",
0
]
},
"_meta": {
"title": "Extract Text"
}
}
})
# run() also passes api_key to the partner nodes in this workflow.
job = client.run(workflow, api_key=api_key)よくある質問
High-resolution images with clear focus on the subject work best, as they provide more detail for the Kling 3.0 model to generate accurate video content.
Yes, you can review and edit the generated prompts in the Preview Prompts group before finalizing the video production.
The workflow uses the PrimitiveInt nodes to set the duration for each shot, allowing for flexible video pacing based on your specifications.
Absolutely, while it's optimized for product videos, you can use any starting frame and reference images to create a variety of video content.