Skip to main content

Natural Lip Sync

Natural lip sync post-processes the viseme stream to produce more natural speech animation. Instead of snapping to every phoneme, it merges similar adjacent shapes and preserves the distinctive ones — the way a real mouth blends sounds during fast speech.

Why

Hitting every phoneme precisely looks robotic. In natural speech the mouth does not have time to fully form each shape; shapes blend, sometimes to the point of not changing at all. The processor mimics that blending while protecting the visually critical shapes (w/u, o, r, l, f/v, and bilabials p/b/m) so articulation still reads.

Enable it

It is one option on useMascotPlayback. This works for every path — offline, mic, and realtime:
That uses DEFAULT_NATURAL_LIPSYNC_CONFIG. To tune it, pass a naturalLipSyncConfig:
naturalLipSyncConfig must be a stable reference — a module constant, or memoized with useState / useMemo. A new object literal on every render reinitializes playback and lip sync breaks after the first audio chunk. This is the single most common integration bug; see Troubleshooting.

Configuration

NaturalLipSyncConfig (all fields optional — unspecified fields fall back to DEFAULT_NATURAL_LIPSYNC_CONFIG): DEFAULT_CRITICAL_VISEME_IDS is [7, 8, 13, 14, 18, 21] — w/u, o, r, l, f/v, and bilabials. Both DEFAULT_NATURAL_LIPSYNC_CONFIG and DEFAULT_CRITICAL_VISEME_IDS are exported so you can derive from them:

Presets

Define presets as module-level constants so the reference is stable:
Start from CONVERSATION. Raise minVisemeInterval / mergeWindow for smoother (lazier) motion; lower them for crisper articulation.

Without React

The processor is exported from @mascotbot/core/rive as a class and a function:
When you enable enableNaturalLipSync on MascotPlayback / useMascotPlayback, this runs internally — you only call it directly if you post-process visemes outside the playback engine.

Next

React hooks

useMascotPlayback options.

Visemes & the timeline

What is being processed.

Troubleshooting

The stable-reference bug.