Lip Sync
Match a KLing video's mouth movement to any audio or text line
- client
- input
- url
- video_id
Talking-head lip sync is a small but crowded field - LivePortrait dominates the local, offline side of it, while paid services like KLing, Hedra, and HeyGen compete on the cloud side. In fact, KLing's lip-sync work is referenced directly in the LivePortrait paper itself; a Reddit thread comparing the two noted that "Kling lip-sync is mentioned in the LivePortrait paper," which tells you the two are actually being benchmarked against each other, not just loosely adjacent tools. This node is the ComfyUI door into KLing's side of that comparison - you're not training or fine-tuning anything, you're sending a video and an audio/text source to KLing's servers and getting a synced result back.
How it works
The node needs two things: a video to sync (via video_id or video_url) and an audio source, packaged through one of two small feeder nodes - Lip-Sync-Audio-Input if you already have a voice recording, or Lip-Sync-Text-Input if you want KLing to generate the speech from text with one of its preset voices. Either one produces a KLING_AI_API_LIPSYNC_INPUT value that plugs into this node's input slot. KLing's servers then do the actual work: analyzing the mouth region across the video frames and regenerating it in sync with the audio track.
The inputs and outputs that matter
input(required) - the packaged audio/text source from one of the two feeder nodes above. You can't skip this; there's no raw-audio shortcut directly intoLip-Sync.face_id(required, but blank by default) - identifies which face to target when a video has more than one person in frame. Leave it empty for single-person videos.video_id/video_url(optional, but you need one) -video_idis the natural chain if the source video came out of another node in this pack (Image2Video,Text2Video,Effects), since it points straight at KLing's own copy without re-uploading.video_urlis the escape hatch for a video that lives elsewhere.
Outputs are url (the finished lip-synced video) and video_id, which you can chain onward into Video-Extender or Video2Audio just like any other KLing-generated clip.
Installing it
ComfyUI Manager: search ComfyUI-KLingAI-API, install, restart. By hand:
cd ComfyUI/custom_nodes
git clone https://github.com/KwaiVGI/ComfyUI-KLingAI-API
cd ComfyUI-KLingAI-API && pip install -r requirements.txt
You need a Client node upstream with a valid KLing AI API key, matched to the right area (global or china) for your account. No local model download - the actual lip-sync model lives entirely on KLing's side.
Common issues
The most common trip-up is trying to feed a raw file path or URL directly into input - it's typed KLING_AI_API_LIPSYNC_INPUT, a custom type that only the two feeder nodes produce, so you always need Lip-Sync-Audio-Input or Lip-Sync-Text-Input in between. Second, if you're chaining from a video you generated earlier in the pack, use video_id rather than trying to grab the url output and re-feeding it as video_url - the id is the more reliable link back to KLing's own copy of the render and avoids relying on a possibly-expiring download URL. And as with every node in this pack, silence or a long wait after queueing usually just means the job is still running on KLing's servers - there's no local progress indicator beyond whatever the Client node's poll_interval is checking on.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| client | KLING_AI_API_CLIENT | — | |
| input | KLING_AI_API_LIPSYNC_INPUT | — | |
| face_id | STRING | — | |
| video_idopt | STRING | — | |
| video_urlopt | STRING | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| url | STRING | — |
| video_id | STRING | — |