BytePlus Seedance 2.5 Draft to Final Video
Preview at 480p, pay for 1080p once
- VIDEO
- last_frame
- response
Generating video with a closed model is an expensive way to find out your prompt was wrong. You wait four minutes, you pay for thirty seconds of 1080p, and the camera does something stupid in the second shot. Draft mode is the obvious fix: render the whole thing at 480p for cheap, look at it, and only then spend the real money. This node is the second half of that loop.
It has almost no inputs, because it doesn't need them. Everything about the final render - prompt, references, duration, aspect ratio, seed, audio setting - is read back from the draft task. You don't re-specify the shot; you point at a draft and say "now for real."
How it works
The draft side happens on a normal Seedance node. Pick Seedance 2.5 Draft or Seedance 2.5 Premium Draft in the model picker, set that node's seed control to fixed (important - otherwise the next run generates a new draft instead of reusing the one you just watched), and run. You get a draft_task_id.
Connect that ID to this node's draft_task_id input, or paste IDs directly - one per line, or comma-separated, if you're queueing several finals at once. Run again. The final comes back at 1080p for 2.5 and 4K for 2.5 Premium.
That's the whole node. watermark, generation_count and non_blocking are the only other controls, and they behave exactly as they do everywhere else in the pack.
Outputs are VIDEO (a list when generation_count is above 1, with the next node running once per video), last_frame (an image batch of final frames, for chaining), and response (the task JSON).
Install and key
cd ComfyUI/custom_nodes
git clone https://github.com/byteplus-sa/ComfyUI-BytePlus-ModelArk
pip install -r ComfyUI-BytePlus-ModelArk/requirements.txt
Restart (ComfyUI 0.31.0 or newer), or install from Manager by searching BytePlus ModelArk. ModelArk API key and region go in Settings → BytePlus, or in user/.env as BYTEPLUS_API_KEY / BYTEPLUS_REGION. No Comfy.org login is needed for this particular node - there are no uploads involved, just IDs.
Where people get burned
The fixed-seed thing is the one that wastes the most money. Leave that upstream node's seed control on random and every press of Run produces a fresh draft; then the final you render isn't the preview you approved, and you've paid for both anyway. The tooltip on this node says it in as many words - it's the single most-missed instruction in the pack.
Second: drafts expire. A draft_task_id is valid for seven days, which is plenty for a session and not enough for "I'll come back to that idea next month." If a draft has aged out, the node can't reconstruct it and you start over from the draft render.
Third: the final reuses your settings, it doesn't freeze the pixels. Same seed, same prompt, same duration - but the model isn't deterministic, so the 1080p render is a very close relative of the draft, not a scaled copy. If your draft had one glorious moment in the middle, assume it'll be different on the final. That's true of every draft-then-final pipeline in this space, and it's the reason the loop is "draft, approve the direction, render final" rather than "draft, approve the frame."
And one that's easy to forget when you're bouncing between the two nodes: your final takes the draft node's generation_count into account upstream, but this node has its own. Three drafts and one final render is the sane shape; three and three is a bill you didn't plan for.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| draft_task_id | STRING | The draft_task_id output of a BytePlus Seedance 2.5 node run with a Draft model (Seedance 2.5 Draft or Seedance 2.5 Premium Draft), or pasted draft task IDs (one per line, or separated by commas). Set that node's seed control to fixed, otherwise the next run generates a new draft instead of reusing the one you reviewed. A draft can be rendered for 7 days after it was created. | |
| watermark | BOOLEAN | false | Whether to add a watermark to the video. |
| generation_count | INT | 1 | Number of separate generations to run in parallel. |
| non_blocking | BOOLEAN | false | Submit the task and return at once; run the node again to collect the finished video. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| VIDEO | VIDEO | The generated video, or every video of a generation_count batch (the next node runs once per video). |
| last_frame | IMAGE | Last frame of each generated video, as one image batch in the same order as the videos. |
| response | STRING | Task responses as JSON. |