BytePlus Seedance First-Last-Frame to Video
Two keyframes and one Pro-only model
- first_frame
- last_frame
- VIDEO
- last_frame
- response
Two images, six seconds of video in between. That's the pitch, and for the specific job it does - a reveal, a transformation, a product rotating from angle A to angle B - no other node in the pack gives you as much control over the outcome. You're not describing the motion, you're bounding it.
If you came here from the 2.5 First-Last-Frame node, know the differences up front: on 1.0 both frames are required (no optional last frame), there are no asset-ID inputs, and there's exactly one model - seedance-1-0-pro. The fast variant has no last-frame support, which is why the picker doesn't offer it.
How it works
model, prompt, first_frame, last_frame, resolution, aspect_ratio and duration are the required set. Both frames are sent inline as base64, so nothing gets uploaded and no Comfy.org login is involved.
promptstill matters. The frames define the endpoints; the prompt tells the model how to travel between them - "the camera slowly pushes in as the petals open" versus "the subject turns to face the light." Skip it and you get an interpolation, which is not always what the shot needs.aspect_ratioincludesadaptive, which follows your frames' framing. Use it unless you specifically want a crop. Your first and last frames should match each other in size and ratio or the transition will visibly jump - that's the model doing its best with contradictory instructions.durationis 2 to 12 seconds. Short is honest here: you're interpolating two fixed moments, and the model has to fill the gap with invented motion.camera_fixed,watermark,enable_offline_inference,generation_countandnon_blockingare the optional set - all four behave as they do on the other Seedance 1.0 nodes.enable_offline_inferenceis worth remembering if you're batching: lower price, up to 48 hours for the result.seedonly controls whether the node re-runs. BytePlus results aren't deterministic.
Outputs are VIDEO (a list when generation_count is above 1), last_frame (final frames as an image batch) and response (task JSON, or the pending task IDs on a non_blocking run). Nothing is written to disk; wire VIDEO into Save Video.
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 install through Manager by searching BytePlus ModelArk. Save the ModelArk API key and region under Settings → BytePlus - the region must be the one the key belongs to, and ap-southeast-1 is the default - or use BYTEPLUS_API_KEY / BYTEPLUS_REGION in user/.env.
Where people get burned
The one that costs you a render: BytePlus has one model with last-frame support on this generation, so if you try to force seedance-1-0-pro-fast into a first-last-frame job (by pasting the ID from another workflow) you'll get an error rather than a cheaper render. Use the picker.
Then the usual two. camera_fixed is a prompt hint, not a lock - BytePlus's own tooltip says the platform appends the instruction but doesn't guarantee the effect, so don't blame the node when the model drifts anyway.
And the cost shape: this is a per-second metered call with a per-generation multiplier, so a "quick look" with generation_count at 4 at 1080p is four separate video bills. Test at 480p, and if you like the direction, render the take you actually want.
One workflow tip that saves real money on this node specifically: if your two frames both came from Seedream, you already know they're consistent. Frames sourced from two different models are where the interpolation falls apart - the model has to reconcile two lighting setups and two senses of what a face looks like, and the middle of the clip is where you see it.
Inputs (13)
| Name | Type | Default | Description |
|---|---|---|---|
| model | COMBO | seedance-1-0-pro-250528 | 1 options: seedance-1-0-pro-250528 |
| prompt | STRING | The text prompt used to generate the video. | |
| first_frame | IMAGE | First frame to be used for the video. | |
| last_frame | IMAGE | Last frame to be used for the video. | |
| resolution | COMBO | The resolution of the output video. | |
| aspect_ratio | COMBO | The aspect ratio of the output video. | |
| duration | INT | 52–12 | The duration of the output video in seconds. |
| seedopt | INT | 00–2147483647 | Seed to use for generation. |
| camera_fixedopt | BOOLEAN | false | Specifies whether to fix the camera. The platform appends an instruction to fix the camera to your prompt, but does not guarantee the actual effect. |
| watermarkopt | BOOLEAN | false | Whether to add an "AI generated" watermark to the video. |
| enable_offline_inferenceopt | BOOLEAN | false | Use the flex (offline) service tier: lower price, results within 48 hours. |
| generation_countopt | INT | 1 | Number of separate generations to run in parallel. With several, generation N uses seed + N so the results differ. |
| non_blockingopt | 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 results as JSON, or the pending task IDs of a non_blocking run. |