NanoBanana - Video Generation (Veo)
Veo 3 on your canvas — including the awkward wait
- source_image
- network
- video_file_path
- video_url
Text-to-video and image-to-video via Google's Veo models, in one node, with no local VRAM involved. Veo 3 is one of the genuinely impressive closed video models - and, uniquely, it generates native audio in the output rather than just silent frames - so if you've been eyeballing Veo from the ImageFX web app and wishing it lived in your graph, this is the node.
The honest caveat up front: video generation is slow, and ComfyUI's worker is single-threaded. This node uses Veo's predictLongRunning endpoint with a polling loop, and while it polls, your UI sits there blocking. That's by design, not a hang - the node prints progress to the log. Budget a minute or two per clip and you won't be surprised.
How it works
It calls generate_videos, which kicks off a long-running operation. The node then polls operation.done every poll_interval seconds until completion or timeout_seconds (default 600) elapses, downloads the resulting MP4s into ComfyUI's output folder with a gemini_veo_ prefix, and hands you both the local file path and the URL. Text-to-video or image-to-video both work - drop an IMAGE into source_image for an img2vid start frame, and it encodes that frame as lossless PNG to preserve identity. Multiple requested videos are all saved; you get the first path/URL back for compatibility and the rest sit on disk for downstream loaders.
One genuinely thoughtful detail: video downloads are SSRF-guarded. The node refuses to fetch from any host that isn't *.googleapis.com or *.googleusercontent.com, so a compromised operation response can't make your worker pull from an internal address. It's the kind of hardening you don't notice until it matters.
The inputs
- api_key, model - Veo 3.1 (incl. fast/lite), Veo 3.0, and Veo 2.0 variants; default
veo-3.0-fast-generate-001. - prompt / negative_prompt - the text directions.
- source_image - optional IMAGE start frame.
- aspect_ratio - 16:9 or 9:16 only.
- number_of_videos - 1–4.
- seed -
-1random;0is a valid seed, fixed after an old version silently dropped it. - duration_seconds - 4–8; Veo 2 supports 5–8s, Veo 3 accepts 4/6/8 depending on variant.
- timeout_seconds, poll_interval - pacing knobs for the wait.
- network - optional proxy route.
Outputs: video_file_path and video_url (both STRING). Wire the path into a video loader or save node.
Installing it
ComfyUI Manager → search NanoBanana2, or
cd ComfyUI/custom_nodes
git clone https://github.com/IxMxAMAR/ComfyUI-NanoBanana2
pip install google-genai
Python 3.10+, google-genai >= 0.8.0, API key. No model files.
Where people get burned
The wait is the top complaint - lower poll_interval if you want snappier cancels, raise timeout_seconds for slow queues. Duration must match what your model variant actually supports; Veo 2 and Veo 3 differ (5–8s vs 4/6/8s), and asking for an invalid duration errors. Remember Veo 2 output is silent - only Veo 3 has native audio. And this is the priciest node in the pack per call; every run is a fresh billed generation, so don't leave it in a loop you didn't intend.
Inputs (13)
| Name | Type | Default | Description |
|---|---|---|---|
| api_key | STRING | — | |
| model | COMBO | veo-3.0-fast-generate-001 | 6 options: veo-3.1-generate-preview, veo-3.1-fast-generate-preview, veo-3.1-lite-generate-preview, veo-3.0-generate-001, veo-3.0-fast-generate-001, veo-2.0-generate-001 |
| prompt | STRING | — | |
| custom_modelopt | STRING | — | |
| source_imageopt | IMAGE | Optional start frame image. | |
| aspect_ratioopt | COMBO | 16:9 | 2 options: 16:9, 9:16 |
| number_of_videosopt | INT | 11–4 | — |
| negative_promptopt | STRING | — | |
| seedopt | INT | -1-1–2147483647 | -1 = random. 0 IS a valid seed (v2.0 silently dropped it). |
| duration_secondsopt | INT | 84–8 | Veo 2 supports 5-8s; Veo 3 supports 4, 6, or 8s depending on model variant. |
| timeout_secondsopt | INT | 60060–1800 | Max time to wait for video generation. |
| poll_intervalopt | INT | 102–60 | Seconds between operation polls. Lower = more responsive cancel, higher = less API noise. |
| networkopt | NB_NETWORK | Optional. Wire a NanoBanana - Network Route node here to route this request through that proxy (e.g. US egress). |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| video_file_path | STRING | — |
| video_url | STRING | — |