---
title: "Talking Character, Any Language — one drawing speaks every language you choose"
tier: hero
format: avatar-video
theme: multilingual-character
persona: creator, educator, marketer, localization, accessibility
duration: 3–10s per clip (chunk + concat for longer)
budget_usd: ~$0.10 (image, once) + ~$8/min of finished talk per language
caps: ["gpt-image", "gemini-text", "gemini-tts", "chatterbox-tts", "inworld-tts", "sync-lipsync-v3", "ffmpeg-burn-subtitles", "ffmpeg-concat", "ffmpeg-export"]
skills: ["talking-avatar"]
showcases:
  - title: "She Speaks · still illustration → talking character (Sync-3)"
    href: "/chapters/talking-character-example.html"
reliability: 3.6 # 5 − portrait gen .3 − tts .2 − sync-3 lipsync .6 − slow-cap timeout risk on long clips .3 + .5 verified E2E showcase (2026-06-22); per-language passes are independent — one language failing doesn't sink the rest
---

# Talking Character, Any Language — agent playbook ⭐

> Paste this whole file (with the BRIEF filled in) into Claude cowork, chat, or Code. **This is the Sync Labs sync-3 (`sync-lipsync-v3`) playbook.** Draw a character **once**, then make it speak — in any language you choose, as many lines as you want. The mouth is generated from the audio, so the same illustration can deliver English, Mandarin, Spanish, Arabic… all from one still.

## What makes this different

`sync-lipsync-v3` is the one cap built to lip-sync a **non-photoreal** still — an illustration, a cartoon, a painted character, a mascot, a single animated frame. `talking-head` / `heygen-twin` expect a real human face; `lipsync` is generic. When the speaker is *drawn*, reach for Sync-3.

And because lipsync follows the **audio waveform**, language is just a property of the voice track — swap the TTS language and the same character speaks it, lips matched. One character, N languages, no re-drawing.

## What you'll get

- **One reusable character still** (`gpt-image`) — front-facing, clean face. Generate it once; it powers every language.
- **One talking-character MP4 per language** via `sync-lipsync-v3` — the same illustration, lip-synced to that language's voice line.
- **(Optional) burned subtitles** in each language (`ffmpeg-burn-subtitles`) + a stitched multi-line cut (`ffmpeg-concat`) + platform aspect (`ffmpeg-export`).

## The BRIEF (fill this in)

```
CHARACTER: <describe the face — e.g. "friendly storybook narrator, young woman, warm watercolor-and-ink, front-facing, clean light background">
           <OR paste a public URL of an existing illustration / animated frame; host local files via scripts/host-local-file.sh>
SCRIPT:    <the line(s) to speak, in ONE source language — e.g. "Hi! I'm just a drawing, but Storyboard gives me a voice.">
LANGUAGES: <the target languages — e.g. "English, Mandarin Chinese, Spanish, Arabic">  (the agent translates SCRIPT into each)
VOICE:     <vibe — e.g. "warm, bright, storybook narrator">  (gemini-tts picks a matching voice per language; or use chatterbox-tts to clone one)
ASPECT:    <9:16 | 16:9 | 1:1>   SUBTITLES: <yes | no>
```

## The pipeline (stages)

1. **Make the character — once.** `create_media(action:"generate", model_override:"gpt-image", prompt:"<CHARACTER> — front-facing head-and-shoulders, looking at viewer, clear unobstructed face, soft even lighting, clean background")`. A clean, front-facing, unobstructed face lip-syncs best. Already have art? Skip this — host it with `scripts/host-local-file.sh` and use that URL.
2. **Per language — translate the line.** For each target language, `gemini-text` translates SCRIPT (keep it short — under ~10s spoken; see the slow-cap note). Or supply your own translation.
3. **Per language — speak it.** `create_media(action:"tts", model_override:"gemini-tts", prompt:"<translated line>", ... )` in that language (`gemini-tts` covers 30+ — see the `talking-avatar` skill for the locale list). For a single cloned voice across languages, use `chatterbox-tts` with an `audio_url` sample. Host the resulting audio if needed.
4. **Per language — lip-sync it.** `create_media(action:"lipsync", source_url:<character still>, audio_url:<that language's voice>, model_override:"sync-lipsync-v3")`. Same still every time; only the audio changes. (You can also just say "use sync-3" / "sync-lipsync" — the router resolves it.)
5. **Finish (optional).** Burn that language's captions with `ffmpeg-burn-subtitles`; `ffmpeg-concat` multiple lines into one delivery; `ffmpeg-export` to ASPECT. (See the `finishing-quality` skill.)

## The repeat / multilingual loop

```
character_url = generate the still ONCE              # stage 1
for lang in LANGUAGES:                               # each pass is independent
    line  = translate(SCRIPT, lang)                  # stage 2
    voice = tts(line, lang)                           # stage 3
    clip  = sync_lipsync_v3(character_url, voice)     # stage 4  ← same still, new audio
    if SUBTITLES: clip = burn_subtitles(clip, line, lang)
    deliver clip as talking-character.<lang>.mp4
```

Run it again next week with a new SCRIPT and the **same `character_url`** — the character stays identical across every video you ever make from it. That's the "repeatable" part: the still is the durable asset; scripts and languages are cheap to swap.

## Tips & honest limits

- **Keep each clip short.** Sync-3 is a slow, premium cap (~$8/min; a ~5s clip takes ~4 min to render). A long single take can exceed the orchestrator's per-job deadline and get cancelled. Split long scripts into <~10s lines, render each, then `ffmpeg-concat`. (This is also better pacing.)
- **Front-facing, clean face wins.** Hair over the mouth, extreme 3/4 angles, or tiny faces hurt the lipsync. Generate the still with the face clear and centered.
- **One character, many languages — by design.** Translate the line, regenerate only the voice + the lipsync clip; never the character. The still is language-agnostic.
- **Photoreal human instead of a drawing?** Use `heygen-twin` (trained twin, most identity-stable) or `talking-head` — Sync-3's edge is *stylized* faces. See the `talking-avatar` playbook for the document-in, read-aloud variant.
- **Voice consistency across languages** isn't guaranteed with `gemini-tts` (it picks a per-language voice). For one recognizable voice in every language, clone it with `chatterbox-tts` (pass the same `audio_url` sample each pass).

Live example: **[She Speaks](/chapters/talking-character-example.html)** — a watercolor portrait reading a line, rendered end-to-end on Livepeer with `sync-lipsync-v3`.
