Skip to main content

State Management

Learn how to track and respond to avatar session states and connection states.

Session States

The avatar session progresses through several states:

IDLE → CREATING → READY → ENDED

ERROR

State Definitions

StateDescription
IDLEInitial state, no session created yet
CREATINGSession is being created (API calls in progress)
READYSession is ready, avatar can be controlled
ENDEDSession has been ended
ERRORAn error occurred during session creation or use

Checking Current State

const state = session.getSessionState();
console.log('Current state:', state);

if (state === 'READY') {
// Safe to call sayText, interrupt, etc.
}

Listening to State Changes

session.on('stateChange', (state) => {
console.log('State changed to:', state);

switch (state) {
case 'IDLE':
console.log('Session not started');
break;
case 'CREATING':
console.log('Creating session...');
break;
case 'READY':
console.log('Avatar ready!');
break;
case 'ENDED':
console.log('Session ended');
break;
case 'ERROR':
console.log('Error occurred');
break;
}
});

Connection States

WebRTC connection states track the streaming connection:

DISCONNECTED → CONNECTING → CONNECTED
↓ ↓
FAILED CLOSED

State Definitions

StateDescription
DISCONNECTEDNo WebRTC connection
CONNECTINGWebRTC connection in progress
CONNECTEDWebRTC streaming active
FAILEDWebRTC connection failed
CLOSEDWebRTC connection closed

Checking Connection State

const connState = session.getConnectionState();
console.log('Connection state:', connState);

if (connState === 'CONNECTED') {
// Video is streaming
}

Listening to Connection Changes

session.on('connectionChange', (state) => {
console.log('Connection state:', state);

switch (state) {
case 'DISCONNECTED':
console.log('Not connected');
break;
case 'CONNECTING':
console.log('Connecting...');
break;
case 'CONNECTED':
console.log('Streaming!');
break;
case 'FAILED':
console.log('Connection failed');
break;
case 'CLOSED':
console.log('Connection closed');
break;
}
});

Complete State Management Example

import { KalturaAvatarSession } from '@unisphere/models-sdk-js';

const session = new KalturaAvatarSession('your-api-key', {
baseUrl: 'https://api.avatar.us.kaltura.ai/v1/avatar-session',
});

// UI elements
const statusEl = document.getElementById('status');
const videoContainer = document.getElementById('avatar-container');

// Session state management
session.on('stateChange', (state) => {
statusEl.textContent = `Session: ${state}`;

switch (state) {
case 'CREATING':
statusEl.className = 'status-creating';
break;
case 'READY':
statusEl.className = 'status-ready';
enableControls();
break;
case 'ENDED':
statusEl.className = 'status-ended';
disableControls();
break;
case 'ERROR':
statusEl.className = 'status-error';
disableControls();
break;
}
});

// Connection state management
session.on('connectionChange', (state) => {
const connStatusEl = document.getElementById('conn-status');
connStatusEl.textContent = `Connection: ${state}`;

switch (state) {
case 'CONNECTING':
videoContainer.classList.add('loading');
break;
case 'CONNECTED':
videoContainer.classList.remove('loading');
videoContainer.classList.add('streaming');
break;
case 'FAILED':
videoContainer.classList.add('error');
alert('Connection failed. Please refresh.');
break;
}
});

// Error handling
session.on('error', (error) => {
console.error('Error:', error.code, error.message);
document.getElementById('error-msg').textContent = error.message;
});

function enableControls() {
document.querySelectorAll('button').forEach((btn) => {
btn.disabled = false;
});
}

function disableControls() {
document.querySelectorAll('button').forEach((btn) => {
btn.disabled = true;
});
}

Best Practices

1. Wait for READY State

Only call control methods when session is READY:

async function safelySpeak(text) {
if (session.getSessionState() !== 'READY') {
console.warn('Session not ready');
return;
}

await session.sayText(text);
}

2. Handle State Transitions

Update UI based on state changes:

session.on('stateChange', (state) => {
// Update button states
document.getElementById('start-btn').disabled = state !== 'IDLE';
document.getElementById('speak-btn').disabled = state !== 'READY';
document.getElementById('end-btn').disabled = state !== 'READY';
});

3. Monitor Connection Quality

session.on('connectionChange', (state) => {
if (state === 'FAILED') {
// Try to reconnect or show error
showReconnectOption();
}
});

Next Steps