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
| State | Description |
|---|---|
IDLE | Initial state, no session created yet |
CREATING | Session is being created (API calls in progress) |
READY | Session is ready, avatar can be controlled |
ENDED | Session has been ended |
ERROR | An 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
| State | Description |
|---|---|
DISCONNECTED | No WebRTC connection |
CONNECTING | WebRTC connection in progress |
CONNECTED | WebRTC streaming active |
FAILED | WebRTC connection failed |
CLOSED | WebRTC 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
- Error Handling - Handle errors gracefully
- Advanced Usage - Custom configurations