Nodes/ComfyUI-BytePlus-ModelArk/BytePlus Seedance 2.5 First-Last-Frame to Video
ComfyUI Node

BytePlus Seedance 2.5 First-Last-Frame to Video

Give the shot a beginning and an ending

By byteplus-sa·Created 8 days ago·Updated about 8 hours ago· 3
BytePlus Seedance 2.5 First-Last-Frame to Video
  • first_frame
  • last_frame
  • VIDEO
  • draft_task_id
  • last_frame
  • response
◄model▾►
◄seed0►
◄watermarkfalse►
◄first_frame_asset_id►
◄last_frame_asset_id►
◄generation_count1►
◄non_blockingfalse►

Text-to-video is a slot machine. Image-to-video is a slot machine that starts where you told it. First-last-frame is the one that lets you direct: here's frame one, here's frame thirty, fill in the motion between them. For anything with a choreographed move - a product turning, a character walking from A to B, a door closing - it's the difference between praying and planning.

This node is the 2.5/2.0 family version, which means the same aggressive pricing and the same native audio generation as its text-to-video sibling, plus both ends of your shot. It also has an escape hatch the 1.0 nodes don't: instead of feeding it images, you can name a BytePlus asset for either frame.

How it works

Under the model picker you get prompt, resolution, duration (4–30 s on 2.5, 4–15 on 2.0), generate_audio and - on 2.5 - output_format. Then, outside the picker, first_frame and last_frame image inputs, first_frame_asset_id and last_frame_asset_id string inputs, seed, watermark, generation_count and non_blocking.

The frame handling is where this node earns its keep. Seedance 2.5 takes the first frame's own aspect ratio and asks for ratio="adaptive", so the frames aren't resized behind your back. On the 2.0 models the pack pre-sizes your local frames to the exact output pixel dimensions before submitting - that's a deliberate fix for a 1080p stretch the core nodes had, and it means you don't have to resize anything yourself.

The two frame sources are mutually exclusive per end: give it a first_frame image or a first_frame_asset_id, not both. And you must give it one of them - a first frame is required, a last frame is optional. If you animate from an asset, first_frame_asset_id also accepts a bare asset://<id> URI or a public https:// image link.

Outputs

VIDEO is a list - with generation_count above 1 you get every generation, each from seed + N, and the next node runs once per video. last_frame hands you the final frame of each video as one image batch, which is exactly what you want for chaining shots: the output of one generation becomes the first_frame of the next. response is the task JSON, and draft_task_id is there when you're running a Draft model.

Wire VIDEO into a Save Video node, or into an upscaler, or into Concatenate Video if you're stitching a sequence.

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 key and region under Settings → BytePlus, or as BYTEPLUS_API_KEY / BYTEPLUS_REGION in user/.env, and enable the model in the ModelArk console. Connected frame images are sent inline - no Comfy.org login needed here, which is why this node is a decent first video test even if you never touch the reference-video features.

Where people get burned

Frame mismatch is the classic. If your two frames are different sizes or wildly different aspect ratios you'll get either an error or a video that lurches at the seam. Match them before you start; the node handles sizing for the 2.0 models but it can't invent a coherent transition between a 16:9 portrait and a 9:16 landscape.

The second trap is believing the seed. It doesn't make results reproducible - it only makes the node re-run. If you liked a take, keep the video, because the same seed will hand you something new.

And the third is the one nobody warns you about until it's billed: generation_count is parallel billed generations, and on video that's the most expensive dial in the pack. Combined with audio generation on by default, a "quick test" at 30 seconds and three variations is a genuinely expensive mistake. Use Draft mode for the exploring, this for the take.

CategoryBytePlus ModelArk

Inputs (9)

NameTypeDefaultDescription
modelCOMBOSeedance 2.5 for the newest model, videos up to 30 seconds and mp4/mov output; Seedance 2.5 Draft for a quick 480p preview whose draft_task_id renders the 1080p final in the BytePlus Seedance 2.5 Draft to Final Video node; Seedance 2.5 Premium for 4k output, and Seedance 2.5 Premium Draft for its 480p preview (rendered in 4k); Seedance 2.0 for maximum quality and 4k; Fast for speed optimization; Mini for the fastest, lowest-cost generation.
seedINT00–2147483647Seed controls whether the node should re-run; results are non-deterministic regardless of seed.
watermarkBOOLEANfalseWhether to add a watermark to the video.
first_frameoptIMAGEFirst frame image for the video.
last_frameoptIMAGELast frame image for the video.
first_frame_asset_idoptSTRINGSeedance asset_id to use as the first frame. Mutually exclusive with the first_frame image input. Also accepts asset://<asset_id> or an https:// image link.
last_frame_asset_idoptSTRINGSeedance asset_id to use as the last frame. Mutually exclusive with the last_frame image input. Also accepts asset://<asset_id> or an https:// image link.
generation_countoptINT1Number of separate generations to run in parallel. With several, generation N uses seed + N so the results differ.
non_blockingoptBOOLEANfalseSubmit the task and return at once; run the node again to collect the finished video.

Outputs (4)

NameTypeDescription
VIDEOVIDEOThe generated video, or every video of a generation_count batch (the next node runs once per video).
draft_task_idSTRINGTask ID of a Seedance 2.5 Draft or Seedance 2.5 Premium Draft run. Connect it to the BytePlus Seedance 2.5 Draft to Final Video node to render the final (1080p, or 4k for Premium). Several drafts (generation_count above 1) give one ID per line.
last_frameIMAGELast frame of each generated video, as one image batch in the same order as the videos.
responseSTRINGTask responses as JSON.