arkennemasis fal · MiniMax H3 Max Lip Sync · $0.05-0.32/s
A photo plus a voice track, for a fraction of Sync's price
- image
- audio
- video
- video_path
- timings
- duration
- seed
- info
A still portrait and an audio track walk into a node
One image, one audio file, and you get back a video of that face speaking the audio with the mouth moving in sync. No driving video, no rig, no mask. This is the digital-presenter move: generate or shoot a portrait, record or synthesise the voice, and get a talking head out of it - the front half of every "avatar news channel" workflow people build with local TTS.
Cost-wise it's the value pick in this pack: $0.05/s at 480p, $0.08/s at 768p, $0.16/s at 1080p, $0.32/s at 2K, plus a 1.2× multiplier on anything over 15 seconds. fal's own worked examples: a 5-second 768p clip is about $0.40, a 30-second one about $2.88. Compare that to the $8-per-minute Sync Lipsync 3 node in the same menu and you can see why this one exists.
Locally, audio-driven avatars are a real option - InfiniteTalk is the fast talking-head default, MultiTalk does multi-speaker, and LTX-2 generates its own synced audio. But they're the fiddly end of the ecosystem: separate packs, dependency clashes, and they're happiest with a front-on, well-lit face. This node handles the awkward inputs.
Inputs that matter
- image - the face to animate. Requires an aspect ratio between 0.4 and 2.5, and the output uses the nearest supported aspect ratio to your image, so a slightly odd crop gets nudged rather than refused. Worth knowing: your untouched 4:5 portrait may come back as something else.
- audio - the thing it syncs to. At least 5 seconds (it's checked before upload - the node validates min/max before spending anything) and up to 15 minutes. The output video matches the supplied audio's duration, which is the useful part: you don't pick a length, the audio does.
- resolution -
480P,768P(default),1080P,2K. Since billing is per second of output, and output length is your audio length, this box is multiplied by the whole track. A 3-minute VO at 2K is 180 × $0.32 before the 1.2× long-video multiplier - about $69. Draft at 480p. - enable_transcription - off by default. Turn it on and the audio gets transcribed to guide the synchronisation. Off, it syncs to the waveform alone. If you're syncing singing, a heavy accent, or a language the transcriber is shaky on, this is the switch to experiment with - and it's also the switch that can hurt, because a bad transcript is worse guidance than none.
- seed -
-1by default. enable_safety_checker - on.
Plus the pack-wide guards: max_cost_usd (default $20 - note that the 3-minute example above trips it, which is the node doing its job), reuse_identical_run, extra_json, max_concurrent (default 1 paid fal call at a time).
Outputs
video, video_path, timings (fal's stage timing), duration (the real output length - sanity-check it against your audio), seed, and info with the request id, the cost estimate and fal's raw answer.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/Hishamahmer/comfyui-arkennemasis
pip install -r comfyui-arkennemasis/requirements.txt
Restart ComfyUI and find it under arkennemasis/fal/Lip Sync/MiniMax. The key goes in the .env next to run_nvidia_gpu.bat:
FAL_KEY=your-key-from-fal.ai/dashboard/keys
Where people get burned
Short audio is rejected before it costs you anything. Under 5 seconds and the node stops at the check stage - no upload, no charge. This is one of the few places where the pack's validation is visible and it's worth trusting.
Aspect ratio gets rounded. The endpoint snaps your image to the nearest supported shape, so a portrait that isn't quite the ratio it wants will be subtly re-framed. Crop deliberately before you upload.
The output is as long as the audio, so long VO is a long bill. There's no duration widget because there's nothing to decide - but there's also nothing to cap. Do a 5-second proof at 480p with the first sentence of the script before you render the whole episode.
Expect the whole head to move, not just the mouth. These models generate the performance, and short audio plus a stiff pose gives you a slightly uncanny result. Give it a real expression to hold.
The hosted path is the licensed path for H3. The H3 open weights' Community License excludes the US, EU, UK and South Korea - so if you're in one of those regions and thinking "I'll just run this locally instead", the weights aren't licensed for you and the endpoint is the clean route.
Cancel is your friend, and it works on fal too. If a long render is clearly going nowhere, ComfyUI's Cancel stops the job server-side rather than letting it bill to completion.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | Image to animate. The aspect ratio must be between 0.4 and 2.5. | |
| audio | AUDIO | Audio to synchronize the mouth movements to, at least 5 seconds long. Supports up to 15 minutes. The output video matches the supplied audio duration. | |
| resolution | COMBO | 768P | Output resolution. Uses the supported aspect ratio nearest the image. |
| enable_transcription | BOOLEAN | false | Transcribe the supplied audio to guide lip synchronization. When disabled, synchronize to the audio without a transcript. |
| seed | INT | -1-1–2147483647 | Random seed; selected randomly if omitted. -1 leaves it to the model. |
| enable_safety_checker | BOOLEAN | true | Enable content safety checks. |
| max_cost_usdopt | FLOAT | 20.00–100000 | Safety cap. If the estimated cost of this run is above this many US dollars the node stops BEFORE sending anything to fal. 0 = no cap. |
| reuse_identical_runopt | BOOLEAN | true | If these exact inputs (the settings AND the same pictures/clips/audio) were already paid for and the files are still in output/fal, return them instead of paying again - also after a ComfyUI restart. Turn off for a fresh take with the same settings. |
| extra_jsonopt | STRING | Advanced: a JSON object merged into the request last, for any fal field this node has no box for. Example: {"seed": 7}. Leave empty normally. | |
| max_concurrentopt | INT | 11–32 | How many paid fal calls may run at the same time in one run, across every fal node. 1 (default) = one after another. This node starts its paid part only while fewer than this many fal calls are running. Once any fal node fails, the ones still waiting are not started, so nothing more is billed. |
Outputs (6)
| Name | Type | Description |
|---|---|---|
| video | VIDEO | — |
| video_path | STRING | — |
| timings | STRING | — |
| duration | FLOAT | — |
| seed | INT | — |
| info | STRING | JSON: request id, cost estimate, saved files and fal's full answer. |