🎬 Veo3.1 首尾帧生成同步 (Grsai)
Veo 3.1 with first AND last frame control, synchronously
- first_frame
- last_frame
- video
- video_url
- response
Veo 3.1 is Google's top video model - 1080p and 4K variants, native audio, and the strongest closed-video quality you can get over an API. The trick this node adds is first/last frame control: give it an opening image and a closing image and it animates between the two, which is how you get a "start somewhere, end somewhere else" shot instead of rolling the dice on a pure text prompt. It's the synchronous Grsai-channel version, so it blocks your queue and shows a progress bar until the MP4 is downloaded.
Inputs:
- prompt - multiline; describes the motion between the frames. Default "A cinematic drone shot". Veo reads this as the instruction for what happens in between.
- model -
veo3.1-fast/veo3.1-fast-1080p/veo3.1-fast-4k/veo3.1-pro/veo3.1-pro-1080p/veo3.1-pro-4k. The Pro models are the quality/cost option; the 4k ones speak for themselves. - aspect_ratio - 16:9 or 9:16.
- first_frame / last_frame - IMAGE inputs. This is the whole point. Wire in a LoadImage (or anything producing an image - including a Nano Banana generation from elsewhere in this pack).
- api_key - optional, pack-wide Grsai fallback.
Outputs: video (a ComfyUI VIDEO, local MP4), video_url (the remote URL), response (status, task ID, credit balance).
Mechanically it uploads the frames to the Grsai API (/v1/video/veo with firstFrameUrl/lastFrameUrl), then polls /v1/draw/result every five seconds for up to 900 seconds, mapping progress onto ComfyUI's progress bar, and downloads the finished file with the yt-dlp-then-curl fallback. The forced re-execution means it will re-run (and re-bill) on every queue pass - same behavior as the other sync video nodes in this pack.
Install is pack-wide:
cd ComfyUI/custom_nodes
git clone https://github.com/jieg9341-lab/ComfyUI-nkxx
Restart; first boot auto-installs requests, pandas, yt-dlp, opencv-python, aiohttp. Grsai key from nkxx.grsai.ai.
Grounded gotchas - and there's a real one:
- Last frame without a first frame is rejected. The code is explicit: "不支持仅使用尾帧生成。必须同时提供首帧。" Veo won't take an end-frame-only request, so if you only have one endpoint image, you're doing text-to-video (or first-frame-only), not last-frame control.
- It blocks. Sync node, minutes per clip, and
IS_CHANGEDre-runs it constantly. For a session, use the async path (VeoFramesSubmitTask_Async→ query →VeoGetNextVideo_Async). - Moderation failures come back as clear Chinese status strings (
输出违规/提示词违规) rather than silent empties - Veo's content filters are strict, and this node surfaces the reason. - Both frames are uploaded before submission; a huge first_frame upload is part of the wall-clock time, so keep frames reasonably sized.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| prompt | STRING | A cinematic drone shot | — |
| model | COMBO | veo3.1-fast | 6 options: veo3.1-fast, veo3.1-fast-1080p, veo3.1-fast-4k, veo3.1-pro, veo3.1-pro-1080p, veo3.1-pro-4k |
| aspect_ratio | COMBO | 16:9 | 2 options: 16:9, 9:16 |
| api_keyopt | STRING | — | |
| first_frameopt | IMAGE | — | |
| last_frameopt | IMAGE | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| video | VIDEO | — |
| video_url | STRING | — |
| response | STRING | — |