KLingAI Lip Sync Async
Lip-sync a long audio file — split, sync, merge, done
- video_path
The plain lip-sync node has a hard ceiling: Kling's lip-sync API can't handle long audio, so a 30-second monologue is out of reach. KLingAI Lip Sync Async is the workaround - it takes the long audio, chops it into segments, runs a separate lip-sync task per segment, waits for all of them, downloads each result, stitches the videos back together, and reattaches the original audio. One node, whole pipeline, and you walk away with a single merged MP4.
It's the most ambitious node in this pack, and it shows: the README lists pydub and FFmpeg as requirements, and the source confirms it - pydub (AudioSegment) does the splitting, and FFmpeg is invoked via subprocess for the merging. requirements.txt installs pydub, but FFmpeg must be on your system PATH or the merge step silently fails. That's the one install step people miss.
Inputs that matter
- api_token (required) - the JWT from the API Key node.
- video_id / video_url (both required in the schema) - the base video to sync. Same rule as the plain lip-sync node: generate the video first.
- audio_type -
urlorfile; audio_url or audio_file carries the actual speech. - segment_duration - 5–30 seconds, default 10. How long each audio chunk is. Shorter segments = more tasks but fewer per-segment failures; the API's limit is the reason this knob exists.
- max_concurrent_tasks - 1–10, default 5. How many lip-sync tasks run at once. Kling's async queue means you're parallelizing your own credit spend here.
- poll_interval_seconds - 10–120, default 30. How often it checks task status.
- output_filename - default
lip_sync_combined, the merged result's name. - sync_adjust_ms - -1000..1000 ms of audio offset correction for the final mux, for when the merged video's audio drifts. 0 is fine until you hear a sync problem.
The output
One output: video_path (STRING) - the location of the merged, audio-restored MP4. No tensors, no task IDs. The node blocks the queue while it does the whole dance, so a long clip means a long queue item.
How the sausage gets made
Split audio with pydub → submit a lip-sync task per segment (bounded by max_concurrent_tasks) → poll all tasks → download every result → concatenate the videos with FFmpeg (-f concat) → remux with the original full audio, applying sync_adjust_ms if set. Files are staged in a temp directory and cleaned up. The "async" in the name refers to the Kling tasks being async - the node itself is a blocking orchestrator.
Where people get burned
- FFmpeg not installed. The single biggest failure. pydub is in
requirements.txt; FFmpeg isn't, and the node won't warn you before the merge blows up. On Windows portable installs, make sureffmpeg.exeis reachable from the shell ComfyUI runs in. - Segment order drift. Segment ordering is the node's proudest claim, but audio desync across merged segments happens - that's what
sync_adjust_msexists for. Start at 0, adjust only if you hear it. - Credit multiplication. 5 concurrent tasks × every segment = a whole pile of individual Kling charges per run. Long audio is genuinely expensive;
max_concurrent_taskschanges speed, not total cost. - It blocks. If you expected to fire it and keep working, no - the queue sits on this node until every segment finishes. Budget the wait.
- Blank audio inputs.
audio_typeselects which field is read; a mismatched pair (typefilebut emptyaudio_file) fails downstream. Feed it coherently.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| api_token | STRING | — | |
| video_id | STRING | — | |
| video_url | STRING | — | |
| audio_typeopt | COMBO | url | 2 options: file, url |
| audio_urlopt | STRING | — | |
| audio_fileopt | STRING | — | |
| segment_durationopt | INT | 105–30 | — |
| max_concurrent_tasksopt | INT | 51–10 | — |
| poll_interval_secondsopt | INT | 3010–120 | — |
| output_filenameopt | STRING | lip_sync_combined | — |
| sync_adjust_msopt | INT | 0-1000–1000 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| video_path | STRING | — |