Cómo funciona (single-provider)
El avatar es opt-in por curso y usa un proveedor para voz y video, por lo que no hay desincronización audio/labios ni un paso de TTS separado:
- HeyGen → LiveAvatar API (modo FULL): el backend crea un session token e inicia una sala LiveKit; el cliente se conecta en LiveKit para video y habla publicando un evento
speak_texten el data channel de LiveKit. HeyGen hace TTS + video. - D-ID → clips/streams: el backend hace proxy de SDP/ICE; el tutor habla con texto y D-ID hace el TTS.
El cliente conecta WebRTC directamente al proveedor — el video nunca pasa por el servidor de Studeia. El backend solo crea la sesión, hace proxy de speak/sdp/ice (D-ID) y registra el uso al detener.
Configuración
- Por tenant: conectar una clave HeyGen o D-ID (cifrada AES-256-GCM), probarla y definir la cuota mensual de minutos.
- Por curso:
Course.avatarProvider,avatarId,avatarVoiceId,avatarQualityy el flagavatarEnabled. Una clave → N avatares (el avatar es un parámetro por sesión).
Seguridad & cuota
- La master API key nunca va al cliente; solo tokens efímeros de sesión/LiveKit. Speak/SDP/ICE son proxied server-side con verificación de
AvatarSession.userId. - La cuota mensual (
monthlyMinuteCap) se verifica antes de iniciar la sesión (fail-closed → quota_exceeded). El uso y el costo se registran enAvatarUsageLog. - Gate:
avatarEnabled+ proveedor/avatar configurado en el curso + matrícula activa + opt-in del alumno.
Degradación elegante
full_avatar → audio_only (TTS + imagen estática) → text_only, por lo que el tutor siempre responde incluso si el proveedor del avatar falla.
Móvil
En móvil el avatar se ejecuta en una WebView que carga la misma página /avatar-embed utilizada en la web (sin módulos WebRTC nativos en Expo); un bridge de React Native reenvía los mensajes de control.
Aún no (roadmap)
La voz de entrada — el alumno hablando con el tutor (voz → STT → chat) — no está implementada. Hoy el avatar es solo de salida (cabeza parlante + voz).