Skip to main content

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 SourceHow to Obtain Track
<audio> elementaudioElement.captureStream().getAudioTracks()[0]
Screen share audiogetDisplayMedia({ audio: true })
Web Audio APIaudioContext.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)
EventCallbackDescription
'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

BrowserMinimum VersionNotes
Chrome94+VP8 + RTCRtpScriptTransform
Firefox117+RTCRtpScriptTransform required
Safari15.4+RTCRtpScriptTransform supported
Edge94+Same as Chrome