Documentation Index
Fetch the complete documentation index at: https://docs.spatius.ai/llms.txt
Use this file to discover all available pages before exploring further.
Web Only: The AvatarKit RTC client path is currently available for Web applications only.
This page covers the Web client side of LiveKit Agents Integration. The client joins the LiveKit room and renders the avatar’s audio and motion stream produced by the LiveKit Agents worker with livekit-plugins-spatius.
This page uses the RTC Adapter with the LiveKit provider. LiveKit Agents is the platform integration; the RTC Adapter (@spatius/avatarkit-rtc) is the Web client adapter used to render the avatar stream from the LiveKit room.
When using the AvatarKit RTC client, do not call new Room() from livekit-client yourself. @spatius/avatarkit-rtc creates and owns the LiveKit Room internally so it can wire audio, avatar motion data, and lifecycle handling correctly. If you need access to the underlying Room instance for advanced LiveKit features, see Native Client Access.
AvatarPlayer API
Code in this section shows type signatures, not copy-paste examples. For runnable code, see the Complete Example at the bottom of the page.
Constructor
new AvatarPlayer(provider: LiveKitProvider, avatarView: AvatarView, options?: AvatarPlayerOptions)
AvatarPlayerOptions
interface AvatarPlayerOptions {
/** Log level: 'info' | 'warning' | 'error' | 'none'. Default: 'warning' */
logLevel?: LogLevel
/**
* Enable jitter buffer for smoother animation playback. When enabled, frames are
* buffered and rendered in sequence at a steady 25fps, absorbing network jitter
* and out-of-order delivery. Default: true.
*/
enableJitterBuffer?: boolean
/**
* Max delay (ms) a frame can sit in the jitter buffer before being rendered.
* Only used when enableJitterBuffer is true. Default: 80 (2 frames @ 25fps).
*/
maxBufferDelayMs?: number
}
Connection
// Connect to LiveKit server
await player.connect(config: LiveKitConnectionConfig): Promise<void>
// Disconnect and clean up
await player.disconnect(): Promise<void>
// Reconnect using last config (useful after stalls)
await player.reconnect(): Promise<void>
// Check connection status
player.isConnected // boolean
player.getConnectionState() // string
LiveKitConnectionConfig
interface LiveKitConnectionConfig {
url: string // LiveKit server URL (wss://...)
token: string // Auth token from your backend
roomName: string // Room name
}
Microphone Control
// Start microphone (requests permission automatically)
await player.startPublishing()
// Stop microphone
await player.stopPublishing()
Custom Audio Publishing
For non-microphone audio sources like audio elements or Web Audio API.
// Publish a custom audio track
await player.publishAudio(track: MediaStreamTrack)
// Stop custom audio
await player.unpublishAudio()
| Audio Source | How to Obtain Track |
|---|
<audio> element | audioElement.captureStream().getAudioTracks()[0] |
| Screen share audio | getDisplayMedia({ audio: true }) |
| Web Audio API | audioContext.createMediaStreamDestination().stream.getAudioTracks()[0] |
unpublishAudio() does not stop the track. You are responsible for calling track.stop() to release the resource.
Native Client Access
Access the underlying LiveKit Room instance for advanced features.
import type { LiveKitRoom } from '@spatius/avatarkit-rtc'
// Via provider (recommended — full type safety)
const room = provider.getNativeClient() // LiveKitRoom | null
// Via player (requires type assertion)
const room = player.getNativeClient() as LiveKitRoom | null
console.log('Remote participants:', room?.remoteParticipants.size)
ConnectionState
type ConnectionState = 'disconnected' | 'connecting' | 'connected' | 'reconnecting' | 'failed'
Events
player.on(event: string, handler: Function)
player.off(event: string, handler: Function)
| Event | Callback | Description |
|---|
'connected' | () | Connected to RTC server |
'disconnected' | () | Disconnected from RTC server |
'error' | (error: Error) | An error occurred |
'connection-state-changed' | (state: ConnectionState) | Connection state changed |
'stalled' | () | Data stream stalled (no frames for 3s) |
When a stalled event fires, the avatar automatically transitions to idle animation. Consider calling player.reconnect() to recover.
Stall recovery example:
player.on('stalled', async () => {
console.log('Stream stalled, reconnecting...')
try {
await player.reconnect()
} catch (error) {
console.error('Reconnection failed:', error)
}
})
Complete Example
import { AvatarPlayer, LiveKitProvider } from '@spatius/avatarkit-rtc'
import { AvatarSDK, AvatarView, AvatarManager, DrivingServiceMode } from '@spatius/avatarkit'
async function init() {
// Initialize AvatarKit for LiveKit transport rendering.
// Note: `region` requires a small type augmentation in @spatius/[email protected] —
// see the Direct Mode Web guide for the avatarkit-region.d.ts snippet.
await AvatarSDK.initialize('your-app-id', {
region: 'us-west',
drivingServiceMode: DrivingServiceMode.host,
})
// `setSessionToken` is not needed on the RTC Adapter path —
// `DrivingServiceMode.host` does not open a Motion Server WebSocket from the client,
// and `AvatarManager.load()` fetches avatar metadata over an App-ID-scoped public endpoint.
// Load avatar and create view
const avatar = await AvatarManager.shared.load('character-id')
const container = document.getElementById('avatar-container')!
const avatarView = new AvatarView(avatar, container)
// Create player
const provider = new LiveKitProvider()
const player = new AvatarPlayer(provider, avatarView, {
logLevel: 'info',
enableJitterBuffer: true,
maxBufferDelayMs: 80,
})
// Listen to events
player.on('connected', () => console.log('Connected!'))
player.on('disconnected', () => console.log('Disconnected!'))
player.on('error', (err) => console.error('Error:', err))
player.on('stalled', async () => {
console.log('Stream stalled, reconnecting...')
await player.reconnect()
})
// Connect to LiveKit server
await player.connect({
url: 'wss://your-livekit-server.com',
token: 'your-livekit-token',
roomName: 'my-room',
})
// Start microphone
await player.startPublishing()
}
Browser Compatibility
| Browser | Minimum Version | Notes |
|---|
| Chrome | 94+ | VP8 + RTCRtpScriptTransform |
| Firefox | 117+ | RTCRtpScriptTransform required |
| Safari | 15.4+ | RTCRtpScriptTransform supported |
| Edge | 94+ | Same as Chrome |