Como funciona (single-provider)
O avatar e opt-in por curso e usa um provedor para voz e video, entao nao ha dessincronia audio/labios nem passo separado de TTS:
- HeyGen → LiveAvatar API (FULL mode): o backend cria um session token e inicia uma sala LiveKit; o cliente conecta no LiveKit para video e fala publicando um evento
speak_textno data channel do LiveKit. A HeyGen faz TTS + video. - D-ID → clips/streams: o backend proxia SDP/ICE; o tutor fala com texto e a D-ID faz o TTS.
O cliente conecta WebRTC direto ao provedor — o video nunca passa pelo servidor do Studeia. O backend so cria a sessao, proxia speak/sdp/ice (D-ID) e grava o uso no stop.
Configuracao
- Por tenant: conectar uma chave HeyGen ou D-ID (cifrada AES-256-GCM), testar e definir a cota mensal de minutos.
- Por curso:
Course.avatarProvider,avatarId,avatarVoiceId,avatarQualitye o flagavatarEnabled. Uma chave → N avatares (o avatar e parametro por sessao).
Seguranca & cota
- A master API key nunca vai ao cliente; so tokens efemeros de sessao/LiveKit. Speak/SDP/ICE sao proxied server-side com checagem de
AvatarSession.userId. - A cota mensal (
monthlyMinuteCap) e verificada antes de iniciar a sessao (fail-closed → quota_exceeded). Uso e custo sao gravados emAvatarUsageLog. - Gate:
avatarEnabled+ provedor/avatar configurado no curso + matricula ativa + opt-in do aluno.
Degradacao graciosa
full_avatar → audio_only (TTS + imagem estatica) → text_only, entao o tutor sempre responde mesmo se o provedor do avatar falhar.
Mobile
No mobile o avatar roda numa WebView que carrega a mesma pagina /avatar-embed usada na web (sem modulos WebRTC nativos no Expo); uma bridge React Native encaminha as mensagens de controle.
Ainda nao (roadmap)
A voz de entrada — o aluno falando com o tutor (fala → STT → chat) — nao esta implementada. Hoje o avatar e somente saida (cabeca falante + voz).