$ cat node-template.py
V
Video Lip Sync
// Synchronizes lip movements in a video to match a provided audio track. Handles audio/video length mismatches with loop modes and configurable silent padding.
Process
Video
template.py
1import os2import sys3import json4import traceback56from gais import Gais78INPUT_DIR = "/data/input"9OUTPUT_DIR = "/data/output"101112def main():13 try:14 input_json = sys.stdin.read()15 execution_input = json.loads(input_json)16 inputs = execution_input.get("inputs", {})1718 video = inputs.get("video", "")19 audio = inputs.get("audio", "")2021 if not video:22 raise ValueError("Video input is required")23 if not audio:24 raise ValueError("Audio input is required")2526 video_path = os.path.join(INPUT_DIR, video)27 if not os.path.exists(video_path):28 raise FileNotFoundError(f"Input video not found: {video_path}")2930 audio_path = os.path.join(INPUT_DIR, audio)31 if not os.path.exists(audio_path):32 raise FileNotFoundError(f"Input audio not found: {audio_path}")3334 os.makedirs(OUTPUT_DIR, exist_ok=True)3536 # Extract optional parameters with defaults37 seed = int(inputs.get("seed", 266))38 loop_mode = str(inputs.get("loop_mode", "pingpong"))39 silent_padding_sec = float(inputs.get("silent_padding_sec", 0.5))4041 print(42 f"Requesting lipsync: seed={seed}, loop={loop_mode}, "43 f"padding={silent_padding_sec}s",44 file=sys.stderr,45 )4647 result = Gais.video.lipsync(48 video=video_path,49 audio=audio_path,50 seed=seed,51 loop_mode=loop_mode,52 silent_padding_sec=silent_padding_sec,53 )5455 # Save result56 out_filename = "lipsync_result.mp4"57 out_path = os.path.join(OUTPUT_DIR, out_filename)58 with open(out_path, "wb") as f:59 f.write(result.content)6061 inference_time = result.metadata.get("inference_time_ms", "unknown")62 print(63 f"Lipsync complete: time={inference_time}ms, "64 f"seed={seed}, loop={loop_mode}",65 file=sys.stderr,66 )6768 output = {69 "video": out_filename,70 }71 print(json.dumps(output, indent=2))7273 except Exception as e:74 error_output = {75 "error": str(e),76 "errorType": type(e).__name__,77 "traceback": traceback.format_exc(),78 }79 print(json.dumps(error_output), file=sys.stderr)80 sys.exit(1)818283if __name__ == "__main__":84 main()$ git log --oneline
v1.6.0
HEAD
2026-05-07v1.3.02026-03-29
v1.2.02026-03-20