Mascotbot Lipsync SDK Quickstart - Animate a Rive Avatar in Minutes
Wire the Mascotbot lipsync SDK into a React app: provider setup, drive a Rive avatar from an audio file, add live microphone input, or use the vanilla core without React.
<MascotProvider> initializes a single LipsyncClient for your app
and exposes it through context.
// app/layout.tsx (or wherever you mount providers)"use client";import { MascotProvider } from "@mascotbot/react";export default function Layout({ children }: { children: React.ReactNode }) { return <MascotProvider apiKey="mascot_pub_…">{children}</MascotProvider>;}
Anywhere inside it, useMascot() gives you the client and status, and
useProcessAudio() fetches a URL, decodes, resamples to 16 kHz, and runs
inference once:
"use client";import { useMascot, useProcessAudio } from "@mascotbot/react";export function Demo() { const { status, error } = useMascot(); const { result, loading } = useProcessAudio("/audio/greeting.wav"); if (status === "initializing") return <p>Loading SDK…</p>; if (status === "error") return <p>{error?.message}</p>; if (loading || !result) return <p>Processing audio…</p>; // result.timeline — serializable viseme timeline (the offline artifact) // result.durationMs — total audio duration // result.speechMs — non-silent ms detected return <pre>{JSON.stringify(result.timeline, null, 2)}</pre>;}
result.timeline is a VisemeTimeline —
hand it to playback below, or JSON.stringify it to persist and replay later
with zero reprocessing.
useProcessAudio runs inference once. Persist result.timeline (it is plain
JSON) and on later loads skip decode + inference entirely:
playback.setTimeline(parseTimeline(JSON.parse(stored))). See
Offline lip sync.
The SDK writes only those inputs. Any other input, data binding, or event on
the file is yours to drive on the raw rive instance
(useMascotRive().rive) — see Rive co-existence.
Or skip authoring entirely and use a ready-made mascot.
The audio worklet is embedded in the SDK and served from a Blob URL by
default — there is no file to copy. Pass workletUrl only if your CSP forbids
worker-src blob:. The same hook handles realtime AI providers via
source: { kind: "mediaStream", stream } — see
Realtime providers.