ComfyUI Node

Runware Sync 3

Make a video's mouth match any audio, without running a lip-sync model locally

By Runware·Created 2 years ago·Updated about a month ago· 140
Runware Sync 3
  • speech
  • video
video
audio
numberResults1
settings.activeSpeakerDetection.autoDetectfalse
settings.emotion(default)
settings.activeSpeakerDetection.frameNumberfalse
settings.activeSpeakerDetection.frameNumber_value0
settings.mode(default)
settings.occlusionDetectionfalse
safetyfalse
safety.checkContentfalse
safety.modefast
settings.syncModecut_off
settings.temperature0.50
ttlfalse
ttl_value60
outputFormatMP4
outputQuality95
advanced_json

Sync 3 is Runware's lip-sync model, and this node is the entire thing in one box: feed it a video and some audio (or just a script), get back a video where the speaker's mouth actually tracks the words. That's a genuinely fiddly job to do locally - the best lip-sync models are heavy, the alignment math is unforgiving, and a bad sync is worse than no sync. On Runware it's a cloud call, which for a task like this is a fair trade: the video processing happens on their GPUs, your machine just shuffles media around.

The node ships with two ways to get the audio in, and the difference matters. You can connect an audio input as a UUID or URL (upload a clip, point at a hosted file, or reuse a Runware result URL), or you can wire a speech socket - the Runware/Params → Speech builder - which lets you type text and have it synthesized server-side before the sync happens. That second path is the one that makes this node feel like magic: type a script, pick a voice, and out comes the video talking.

How it works

It's the standard pack machinery. The node (sync:lipsync@3, videoInference) builds a request, sends it over REST through the runware-sdk, and when the job finishes downloads the result into a native VIDEO output. The SDK handles uploading your input video and audio so Runware's servers can see them. The settings block is where the actual lip-sync behavior lives, and it's worth knowing what each knob does:

  • settings.mode - which region of the face gets animated (full face vs. just the mouth area, among a few options).
  • settings.emotion - an emotional tone applied during re-animation, from a dropdown.
  • settings.temperature - expressiveness of the lip movements; higher is livelier, lower is stiffer.
  • settings.syncMode - what happens when audio and video lengths don't match. Default cut_off trims to the shorter one; other modes stretch or pad.
  • settings.tts.provider - defaults to elevenlabs, with similarityBoost and stability sliders for voice control. This is the voice the Speech builder uses.
  • settings.activeSpeakerDetection.autoDetect - for multi-person video, automatically target whoever is speaking. Turn this on and you don't have to supply face coordinates.
  • settings.occlusionDetection - handle faces that get partially covered during the clip.

The advanced_json field is the escape hatch: Runware documents that it accepts settings.activeSpeakerDetection.boundingBoxes, coordinates, and settings.segments as raw JSON, so if you want manual control over who's talking and when, that's where it goes.

The inputs that matter

The only required input is video (a UUID or URL string). For a first run, keep it simple:

  • Wire your clip into video.
  • Type your script into a Speech builder and connect it to speech - or connect a pre-made audio file to audio instead.
  • Leave settings.syncMode at cut_off and let settings.temperature sit around 0.5.
  • If there are multiple people in frame, flip settings.activeSpeakerDetection.autoDetect on.

Output is a single video (VIDEO) - wire it into a video preview/save node. Output format defaults to MP4.

Install and API key

Shared install with the whole pack:

cd ComfyUI/custom_nodes
git clone https://github.com/Runware/ComfyUI-Runware
pip install -r ComfyUI-Runware/requirements.txt

Restart ComfyUI, or grab Runware from ComfyUI Manager. Needs an API key from runware.ai/api-keys - set it in ComfyUI Settings → Runware API key, via RUNWARE_API_KEY, or runware auth login.

Gotchas

The number one beginner trap here is feeding the node a local video file as if it were a path - the video input wants a UUID or URL, not a local filesystem path, so upload your clip first (Runware Upload Image is for images; for video you'll typically use the SDK upload or a hosted URL). Also remember that a speech-driven run means two cloud services are involved (TTS plus lip-sync), so the cost and latency are both higher than a plain video pass. And sync quality is content-dependent: long gaps with no dialogue are where syncMode and temperature earn their keep. If the mouth drifts, nudge temperature down and re-check your audio length.

CategoryRunware/Video/sync

Inputs (20)

NameTypeDefaultDescription
videoSTRINGVideo input (UUID or URL).
speechoptRUNWARE_SPEECH
audiooptSTRINGAudio input (UUID or URL).
numberResultsoptINT11–4Number of results to generate. Each result uses a different seed, producing variations of the same parameters.
settings.activeSpeakerDetection.autoDetectoptBOOLEANfalseAutomatically detect and target the active speaker.
settings.emotionoptCOMBO(default)Emotional tone for performance re-animation.
settings.activeSpeakerDetection.frameNumberoptBOOLEANfalseEnable to set settings.activeSpeakerDetection.frameNumber. Off uses the model's default.
settings.activeSpeakerDetection.frameNumber_valueoptINT0Frame index corresponding to the provided face coordinates.
settings.modeoptCOMBO(default)Controls the region of facial animation applied during lip sync.
settings.occlusionDetectionoptBOOLEANfalseEnable occlusion handling for obstructed faces.
safetyoptBOOLEANfalseEnable to set safety. Off uses the model's default.
safety.checkContentoptBOOLEANfalseEnable or disable content safety checking.
safety.modeoptCOMBOfastSafety checking mode for video generation.
settings.syncModeoptCOMBOcut_offSynchronization strategy when audio and video durations don't match.
settings.temperatureoptFLOAT0.500–1Expressiveness of lip sync and facial movements.
ttloptBOOLEANfalseEnable to set ttl. Off uses the model's default.
ttl_valueoptINT60Time-to-live (TTL) in seconds for generated content. Only applies when `outputType` is `URL`.
outputFormatoptCOMBOMP4File format for the generated video.
outputQualityoptINT9520–99Compression quality of the output. Higher values preserve quality but increase file size.
advanced_jsonoptSTRINGOptional JSON merged into the request. For: settings.activeSpeakerDetection.boundingBoxes, settings.activeSpeakerDetection.coordinates, settings.segments

Outputs (1)

NameTypeDescription
videoVIDEO