Advanced Usage
Advanced topics and customization options for the Kaltura Avatar Client SDK.
Understanding the apiKey Parameter
The KalturaAvatarSession constructor takes an optional apiKey parameter:
// FE-only control - SDK creates the session
const session = new KalturaAvatarSession('your-kaltura-session', config);
await session.createSession({ avatarId: 'avatar-123' });
// BE/FE split - Backend creates session, SDK displays only
const session = new KalturaAvatarSession(undefined, config); // No apiKey!
const { sessionId, token } = await myBackend.createSession();
await session.initSession({ sessionId, token });
When to pass apiKey:
- Only when you want the SDK to create sessions (demos, quick testing)
- Not recommended for production
When to omit apiKey:
- When backend creates sessions (recommended)
- In
initSession()flow - token comes from backend
Custom Logging
Configure logging levels for debugging:
const session = new KalturaAvatarSession('your-api-key', {
baseUrl: '...',
logLevel: 'debug', // 'debug' | 'info' | 'warn' | 'error'
});
Log levels:
debug- All logs including verbose debug infoinfo- Normal operation logs (default)warn- Warnings onlyerror- Errors only
Say Text with Streaming Support
Use sayText with turnId and isFinal parameters for LLM streaming:
// Generate unique turn ID for this conversation turn
const turnId = `turn-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
// Streaming chunks from LLM
const chunks = ['Hello, ', 'this is ', 'a ', 'streaming ', 'response.'];
for (let i = 0; i < chunks.length; i++) {
const isFinal = i === chunks.length - 1; // Last chunk?
await session.sayText(chunks[i], turnId, isFinal);
}
Multiple Sessions
Run multiple avatar sessions simultaneously:
const session1 = new KalturaAvatarSession('your-api-key', config);
const session2 = new KalturaAvatarSession('your-api-key', config);
await Promise.all([
session1.createSession({
avatarId: 'avatar-1',
videoContainerId: 'container-1',
}),
session2.createSession({
avatarId: 'avatar-2',
videoContainerId: 'container-2',
}),
]);
// Control them independently
await session1.sayText('Hello from avatar 1');
await session2.sayText('Hello from avatar 2');
Custom Video Element Handling
If you need full control over the video element:
// Create session without auto-attach
await session.createSession({
avatarId: 'avatar-123',
});
// Get the media stream manually
const stream = session.getMediaStream(); // Advanced: not in basic API
// Create your own video element
const video = document.createElement('video');
video.srcObject = stream;
video.autoplay = true;
video.playsinline = true;
video.style.width = '100%';
// Custom container setup
const container = document.getElementById('my-custom-container');
container.appendChild(video);
Connection Quality
Monitor connection quality:
session.on('connectionChange', (state) => {
if (state === 'CONNECTED') {
console.log('Streaming started');
} else if (state === 'FAILED') {
console.log('Poor network quality');
}
});
TypeScript Tips
Full TypeScript support with no additional packages needed:
import type { AvatarConfig, CreateSessionOptions, SessionState, ConnectionState, AvatarError, AvatarErrorCode } from '@unisphere/models-sdk-js';
const config: AvatarConfig = {
baseUrl: 'https://api.avatar.us.kaltura.ai/v1/avatar-session',
logLevel: 'info',
};
const options: CreateSessionOptions = {
avatarId: 'avatar-123',
voiceId: 'voice-456',
videoContainerId: 'avatar-container',
};
Next Steps
- Examples - Complete working examples
- Production Deployment - Best practices
- Troubleshooting - Common issues and solutions