FSL Google Veo Generator
FSL Google Veo Generator — cloud video inside ComfyUI, billing required
- image_input
- VIDEO_PATH
The FSL pack's video arm. FSLVeoGenerator sends a prompt - and optionally an image - up to Google's Veo API, polls until the job is done, downloads the MP4, and hands you back a file path as a STRING output. It's the "Animator" in Fred LeFevre's creative-director workflow, and it's the only node in this pack where you genuinely cannot skip the paid tier: Veo requires a Google Cloud project with billing enabled. Free AI Studio keys will get you 403/404s.
The value proposition is real if you've ever tried to run video locally: Veo 3.1 generates with native audio, which the KB's closed-source-models.md calls a genuine capability gap with no open-source equivalent yet. You're trading local VRAM for an API bill, but you get a model no consumer GPU is running.
Two modes, and they're not optional
The node's behavior flips entirely on whether image_input has a wire:
- Image-to-Video: connect an image, and Veo animates your pixels. But the README is loud about the catch: duration and aspect ratio are ignored in this mode. The Veo API rejects custom configs when an image is present, so the node strips them and uses model defaults (usually ~5s, native aspect). The sliders stay in the UI but do nothing.
- Text-to-Video: leave
image_inputdisconnected, and you get full control -duration_seconds(5–8s) andaspect_ratio(16:9, 9:16, 1:1, 4:3, 3:4).
The classic mistake: leaving an image connected and typing "make a video of a spaceship." The model tries to morph your input into a spaceship, or the API errors out. Want fresh generation from words? Physically drag the wire off the image_input pin.
How the download actually works
This is the part the node gets right. Veo generation takes minutes, and Google's Python SDK tends to time out on big files, so the node bypasses it: it grabs the operation name, polls generativelanguage.googleapis.com directly every 10 seconds for up to 10 minutes, retries 503/429 errors with exponential backoff, then downloads the MP4 bytes. Output lands in ComfyUI's output/ folder as Veo_Vid_<timestamp>.mp4.
save_location is a string, and it's relative to the ComfyUI root folder, not the output folder - the README spells this out: my_videos → ComfyUI/my_videos/, output/my_videos → ComfyUI/output/my_videos/, and an absolute path like C:/Videos/ works too. The code sanitizes the path so it can't escape the output base.
The outputs and where they go
One output: VIDEO_PATH, a STRING. It's an output node by design, so it doesn't chain further - you feed the path into a Load Video / Video Info node to preview it, or just look in the folder. prompt comes straight from the FSLGeminiChat VIDEO_PROMPT output in the full workflow, or you can type it directly.
Install & troubleshooting
Manager → "ComfyUI FSL Nodes", or clone + pip install -r requirements.txt (essentially google-genai, requests, pillow, numpy). No models to download - it's all server-side.
Common failure modes, grounded in the README:
- "video is not a valid path" - the node failed and passed back an error string instead of a path. Read the ComfyUI console for the real cause; it's almost always the key or a safety filter.
- "RAI Media Filtered" - Veo blocked it. It's strict about photorealistic people; describe the action rather than the person, and know that 3.1 stays strict regardless.
- duration "out of bound" errors - you're on an old version in image-to-video mode. Update the pack; v6.5+ auto-strips the config when an image is detected.
And the $0 gatekeeper: if the prompt is empty, the node skips the API call and returns None - that's how the chat agent lets you converse without spending money on video.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| api_key | STRING | — | |
| prompt | STRING | — | |
| model_name | COMBO | veo-3.1-generate-preview | 3 options: veo-3.1-generate-preview, veo-3.0-generate-preview, veo-2.0-generate-001 |
| duration_seconds | INT | 55–8 | — |
| aspect_ratio | COMBO | 16:9 | 5 options: 16:9, 9:16, 1:1, 4:3, 3:4 |
| image_inputopt | IMAGE | — | |
| save_locationopt | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| VIDEO_PATH | STRING | — |