Concurrent Submit | zhenzhen-vidu-q4-preview(4合1)
Ten Vidu videos in flight — and why ten is the number that matters
- api_config
- image1
- image2
- image3
- image4
- image5
- image6
- image7
- image8
- image9
- image10
- image11
- image12
- image13
- image14
- image15
- audio1
- audio2
- audio3
- task
Video is where serial API workflows really hurt. A Vidu Q4 job is not a 30-second round trip - it's minutes, and the longer and higher-resolution you go, the worse it gets. One clip at a time means a five-shot sequence is your entire evening of clicking Queue.
This node is the concurrent submit version of the Vidu Q4 Preview node: same four models, same widget list, same fifteen image slots and three audio slots, but it returns a task handle and fires the job into a pool rather than waiting for it. Ten of these run at once, which is exactly the point and also exactly the constraint, because the pack's video pool is a third the size of its image pool.
Why the pool is 10 and not 30
The pack runs two module-level thread pools: 30 workers for anything whose primary output is an image, 10 for anything video. This node picks the video pool automatically - the choice is derived from the node's return type, not from a setting. Both are overridable from the environment before ComfyUI starts:
COMFLY_VIDEO_CONCURRENCY=10
COMFLY_VIDEO_PENDING=10
Ten concurrent renders is a sensible default for a reseller relay: metering is per second of generated video, and the upstream queue is shared with everyone else on the channel. It also means you'll hit the ceiling fast - with ten running and ten waiting, the 21st submit blocks its ComfyUI execution thread until a slot frees. Nothing is broken when that happens, the graph is just waiting, and it will not be fast.
Shipping the tasks somewhere
The output here is task, of type COMFLY_VIDEO_FUTURE, which does not plug into Save Video. The other half of the pair is Concurrent Collect Videos (10): task_1 through task_10 in, video_1 … video_10 plus a status string out. Each video_N output is a real VIDEO and wires straight to Save Video.
Ordering is by slot, not by finish time - the shortest clip on task_3 doesn't jump ahead of the 16-second 4K one on task_1. That's the feature: if you're building a shot sequence to cut together, slot order is your edit order, and this saves you sorting a folder of timestamped downloads.
failure_mode decides what a dead job looks like. fail_fast (the default) raises and cancels everything still queued - which for video means throwing away work that's already been paid for and is minutes deep. placeholder returns an empty video adapter for that slot and lets the rest of the batch finish, with a status JSON naming the failed slots and a sanitized reason (keys and URLs stripped). On long video jobs, placeholder is the choice you'll regret less.
The inputs don't change
Because the submit node is generated from the serial node's own INPUT_TYPES, every widget carries over: model (the two -r2v variants and their -global- twins, plus i2v), prompt, seconds (3–16), resolution (540p → 4k), ratio, generate_audio, is_rec, watermark, audio_url1–audio_url3, the audio1–audio3 AUDIO inputs, image1 … image15, skip_error, seed.
The mode rules are enforced per node, so a mixed graph is fine as long as each node obeys its own: i2v wants exactly image1, r2v wants one to fifteen images and a non-empty prompt, and an audio slot takes either a public MP3 URL or a local AUDIO, never both. seed is a cache seed, never sent to the API - ten fixed nodes with unchanged inputs serve cached results, while a stray randomize across all ten is ten fresh renders.
Using it without setting money on fire
seconds and resolution are both multipliers on the bill. The sane loop: fan out ten cheap 3-second 540p probes with different prompts or references, see which one has legs, then re-run only that prompt at 720p or 1080p for the real length. The collector's slot ordering makes "which was which" trivial, which is the whole reason to batch this way instead of reading a website's task list. Plan around the polling too - 4-second intervals with an 1,800-second ceiling per job, so set SEEDANCE_MAX_POLL_TIME higher before launching ComfyUI if you're queuing several 4K clips.
Installing it
It comes with the pack:
cd ComfyUI/custom_nodes
git clone https://github.com/T8mars/Comfyui-zhenzhen
# restart, then search "Concurrent"
Submits live under zhenzhen/…/Concurrent Submit, the collector under zhenzhen/Concurrent Collect. Key setup is unchanged: Zhenzhen API Settings into each node's api_config - and keep in mind that key is embedded in whatever workflow you save. Local AUDIO references go through FFmpeg, which the portable build already ships.
Where people get burned
Do not re-queue a graph whose jobs are still in flight. The collector is marked always-changed, and fresh submits are fresh paid renders; there's no dedupe across a second Queue press.
skip_error plus fail_fast is a confusing combination. The submit node's skip_error turns a failure into a 512×512 dark-blue "Seedance request failed" clip that counts as success - so the batch reports green and one of your shots is an error card. Use it deliberately, and read status.
The collector can sit there for a very long time. Ten 16-second 4K jobs, each polling for up to half an hour, is a genuinely long single node execution. Expected, not a hang - but plan the batch size around your patience, not just your budget.
Downloads are the weak link, not generation. The pack retries media fetches with a 120-second floor and falls back to a proxy-free session when a stale HTTP_PROXY/HTTPS_PROXY breaks the transfer. If clips render but never land, suspect that path - and if the relay endpoint is unreachable at all (the README's 443 case), every node in the graph fails identically and no amount of pool tuning helps.
Inputs (32)
| Name | Type | Default | Description |
|---|---|---|---|
| model | COMBO | vidu-q4-preview-i2v | 4 options: vidu-q4-preview-i2v, vidu-q4-preview-r2v, vidu-q4-preview-global-i2v, vidu-q4-preview-global-r2v |
| prompt | STRING | R2V requires a prompt; empty I2V uses natural subtle motion. | |
| seconds | COMBO | 5 | 14 options: 3, 4, 5, 6, 7, 8, +8 |
| resolution | COMBO | 720p | 5 options: 540p, 720p, 1080p, 2k, 4k |
| ratio | COMBO | 16:9 | 5 options: 16:9, 9:16, 1:1, 4:3, 3:4 |
| generate_audio | BOOLEAN | true | — |
| is_rec | BOOLEAN | true | — |
| watermark | BOOLEAN | false | — |
| audio_url1 | STRING | Public MP3 URL or local AUDIO, not both. | |
| audio_url2 | STRING | Public MP3 URL or local AUDIO, not both. | |
| audio_url3 | STRING | Public MP3 URL or local AUDIO, not both. | |
| api_configopt | ZHENZHEN_SEEDANCE2_CONFIG | — | |
| image1opt | IMAGE | — | |
| image2opt | IMAGE | — | |
| image3opt | IMAGE | — | |
| image4opt | IMAGE | — | |
| image5opt | IMAGE | — | |
| image6opt | IMAGE | — | |
| image7opt | IMAGE | — | |
| image8opt | IMAGE | — | |
| image9opt | IMAGE | — | |
| image10opt | IMAGE | — | |
| image11opt | IMAGE | — | |
| image12opt | IMAGE | — | |
| image13opt | IMAGE | — | |
| image14opt | IMAGE | — | |
| image15opt | IMAGE | — | |
| audio1opt | AUDIO | — | |
| audio2opt | AUDIO | — | |
| audio3opt | AUDIO | — | |
| skip_erroropt | BOOLEAN | false | — |
| seedopt | INT | 00–18446744073709550000 | ComfyUI cache seed only; not sent to the API. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| task | COMFLY_VIDEO_FUTURE | — |