HappyHorse 1.1 · Reference to Video
Keep the character, lose the first-frame leash
- reference_image_urls
- video
- task id
Image-to-video has a built-in limitation nobody warns you about: your first frame is frame one of the result, so the shot can never open on something else. Reference-to-video throws that away. You hand the model pictures of the subject - a person, a product, a jacket - and describe a shot, and the model builds the shot with that subject in it. Different job, and for anything with a character in it, a much better one.
HappyHorse is Alibaba's video model, served through PopNow rather than run locally. The name is a leaderboard codename, not a product roadmap hint, and there are no weights to download - 1080p clips with sound, nine aspect ratios, billed per second of output.
How the plumbing works
This pack doesn't ship one hand-written node per model. It reads PopNow's catalog and its per-model JSON input schema at ComfyUI startup and builds a node class for each model-and-task pair, which is why the widget list here matches the model's real API exactly and why a model PopNow launches next month shows up as a node after a restart with no pack update. The class name is derived from the model id, so saved workflows keep resolving.
Two consequences worth internalising. Inputs you can't see are inputs the model doesn't take. And when a schema says "list of images", the node grows an Autogrow socket group rather than a single socket.
The inputs that matter
prompt- "Reference images in the order used by the prompt" is the tooltip on the images field, which tells you the prompt is where the images get named. Write it as if you're labelling them; the model isn't guessing which picture is the hero.reference_image_urls- this is the Autogrow group. It starts with one socket and grows another every time you connect something, up to the model's cap. Each connected socket is uploaded separately and sent as an ordered list. Connect your Load Image (or a wholeIMAGEbatch - a batch on one socket counts as several pictures) and stop when the reference set is right.aspect_ratio- 16:9 by default. Because there's no source frame to inherit from, this one matters, and it's the field people forget exists on the sibling I2V node.resolution- 720p default, 1080p available.duration_seconds- 3 to 15, default 5. The meter runs per second ("from 21 credits ($0.21) per second"), so this is where a test becomes an expensive test.seed- fixed by default. Queueing the same graph again returns the cached clip rather than a new one, which is deliberate: every run is billed.
Outputs are video - wire it to Save Video, it won't preview itself - and task id, which is the string you paste into the PopNow API console when a run needs support.
Install
Same pack, same two minutes:
cd ComfyUI/custom_nodes
git clone https://github.com/popnow-ai/popnow-comfyui
# restart ComfyUI
Manager users: search PopNow, Install, restart. No dependencies are declared - the nodes use only what ComfyUI already ships, plus a POPNOW_API_KEY. Create a key at popnow.ai/api/console/keys, paste it in Settings → PopNow (or export POPNOW_API_KEY on a headless box so it's never in a workflow file), then restart once more so the catalog comes from your account.
If you used the old single-file custom_nodes/popnow_api.py, delete it. The PopNow Generate node in this pack is the same node type and saved workflows keep working.
Real problems, and the one that bites
Reference order drift. With several references wired in, the model leans on whichever it can match to the prompt words. Mismatched order is the usual cause of "it used the wrong face" - the sockets are ordered top to bottom, so reorder your images, not your prose.
A refused combination comes back as PopNow 40004, naming the setting to change; 40201 is an empty credit balance. Both are refunded where nothing was generated.
The cancelled job keeps going. Interrupting in ComfyUI stops the wait. The task continues on PopNow's servers and is charged if it succeeds, and task id is how you find it afterwards.
Cheap habit before a long clip: set Settings → PopNow → Max credits per run to something you're willing to lose. Runs quoted above the ceiling stop before anything is held, and each node's badge shows the going rate for whatever options you've picked.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| prompt | STRING | Describe the scene, action, camera movement, and timing. | |
| reference_image_urls | COMFY_AUTOGROW_V3 | Reference images in the order used by the prompt. | |
| aspect_ratio | COMBO | 16:9 | Output aspect ratio. |
| resolution | COMBO | 720p | Output video resolution. |
| duration_seconds | INT | 53–15 | Output duration in seconds. Any integer from 3 to 15 is accepted; longer clips cost proportionally more. |
| seed | INT | 00–2147483647 | Same seed and settings, same result. Set 'control after generate' to randomize to get a new result on every run; every run is billed. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| video | VIDEO | — |
| task id | STRING | The PopNow task id, for the API console logs or support. |