Optimize your realtime video integration for quality, performance, and reliability
Build production-ready realtime video integrations. This guide covers camera setup, connection management, prompt strategy, error handling, and mobile-specific considerations.
Always use the model’s built-in constraints when requesting camera access. Each model defines the fps, width, and height it expects — passing these directly avoids scaling artifacts and wasted bandwidth.
Requesting a resolution that doesn’t match the model’s expectations forces the browser to scale the video. This adds latency and can reduce output quality.
On mobile devices, specify the facingMode to select the camera:
const stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: "user", // front camera // facingMode: "environment" // back camera frameRate: model.fps, width: model.width, height: model.height, },});
When switching between front and back cameras, recapture the stream — each camera has different hardware capabilities that affect resolution and frame rate.
Establishing a WebRTC connection takes a few hundred milliseconds. Don’t reconnect just to change the style or prompt — use set() or setPrompt() instead:
// Good: update prompt without reconnectingawait realtimeClient.set({ prompt: "New style" });// Avoid: disconnecting and reconnecting for every prompt changerealtimeClient.disconnect(); // unnecessaryawait client.realtime.connect(stream, { model, ... }); // slow
Enable enhance: true (the default) to let Decart expand short prompts into detailed descriptions. This dramatically improves output quality for simple inputs:
// Short prompt → enhanced automaticallyrealtimeClient.setPrompt("Anime style"); // enhanced behind the scenes// Detailed prompt → disable enhancement for full controlrealtimeClient.setPrompt( "A highly detailed 2D anime character with smooth cel-shaded lines, soft pastel highlights, large expressive eyes", { enhance: false });
Start with enhancement enabled. Only disable it when you need exact control over the prompt text.
Since set() replaces the entire state, always include every field you want to keep. When using Lucy 2 with both a prompt and reference image, include both in every call:
// Good: atomic updateawait realtimeClient.set({ prompt: "Transform into this character", image: characterPhoto, enhance: true,});// Avoid: separate calls can cause flickeringawait realtimeClient.setPrompt("Transform into this character");await realtimeClient.setImage(characterPhoto); // brief mismatch between prompt and image
The SDK automatically reconnects when an unexpected disconnection occurs (e.g., network interruption). It retries with exponential backoff up to 5 times:
Connection drops → state moves to "reconnecting"
SDK retries with increasing delays
If reconnection succeeds → state moves back to "generating"
If all retries fail → state moves to "disconnected" and an error event fires
You don’t need to implement reconnection logic yourself — but you should update your UI to reflect the reconnecting state.