Files
sgse-app/CORRECOES_JITSI.md
deyvisonwanderley 5122eacddd feat: enhance CallWindow with error handling and track management
- Added error handling logic to manage Jitsi connection and track creation errors, providing user-friendly feedback through the new ErrorModal.
- Introduced functionality to dynamically create and manage local audio and video tracks during calls.
- Updated Jitsi configuration to separate host and port for improved connection handling.
- Refactored call initiation logic to ensure robust error reporting and user guidance during connection issues.
2025-11-21 19:52:50 -03:00

8.0 KiB

Correções Implementadas para Integração Jitsi

Resumo das Alterações

Este documento descreve todas as correções implementadas para integrar o servidor Jitsi ao projeto SGSE e fazer as chamadas de áudio e vídeo funcionarem corretamente.


1. Configuração do JitsiConnection

Problema Identificado

  • A configuração do serviceUrl e muc estava incorreta para Docker Jitsi local
  • O domínio incluía a porta, causando problemas na conexão

Correção Implementada

// Separar host e porta corretamente
const { host, porta } = obterHostEPorta(config.domain);
const protocol = config.useHttps ? 'https' : 'http';

const options = {
  hosts: {
    domain: host, // Apenas o host (sem porta)
    muc: `conference.${host}` // MUC no mesmo domínio
  },
  serviceUrl: `${protocol}://${host}:${porta}/http-bind`, // BOSH com porta
  bosh: `${protocol}://${host}:${porta}/http-bind`, // BOSH alternativo
  clientNode: config.appId
};

Arquivo modificado:

  • apps/web/src/lib/components/call/CallWindow.svelte

Arquivo criado/atualizado:

  • apps/web/src/lib/utils/jitsi.ts - Adicionada função obterHostEPorta()

2. Criação de Tracks Locais

Problema Identificado

  • Os tracks locais não estavam sendo criados após entrar na conferência
  • Faltava o evento CONFERENCE_JOINED para criar tracks locais

Correção Implementada

conference.on(JitsiMeetJS.constants.events.conference.CONFERENCE_JOINED, async () => {
  // Criar tracks locais com constraints apropriadas
  const constraints = {
    audio: estadoAtual.audioHabilitado ? {
      echoCancellation: true,
      noiseSuppression: true,
      autoGainControl: true
    } : false,
    video: estadoAtual.videoHabilitado ? {
      facingMode: 'user',
      width: { ideal: 1280 },
      height: { ideal: 720 }
    } : false
  };

  const tracks = await JitsiMeetJS.createLocalTracks(constraints, {
    devices: [],
    cameraDeviceId: estadoChamada.dispositivos.cameraId || undefined,
    micDeviceId: estadoChamada.dispositivos.microphoneId || undefined
  });

  // Adicionar tracks à conferência e anexar ao vídeo local
  for (const track of tracks) {
    await conference.addTrack(track);
    if (track.getType() === 'video' && localVideo) {
      track.attach(localVideo);
    }
  }
});

Arquivo modificado:

  • apps/web/src/lib/components/call/CallWindow.svelte

3. Gerenciamento de Tracks

Problema Identificado

  • Tracks locais não eram armazenados corretamente
  • Falta de limpeza adequada ao finalizar chamada

Correção Implementada

  • Adicionada variável de estado localTracks: JitsiTrack[] para rastrear todos os tracks locais
  • Implementada limpeza adequada no método finalizar():
    • Desconectar tracks antes de liberar
    • Dispor de todos os tracks locais
    • Limpar referências

Arquivo modificado:

  • apps/web/src/lib/components/call/CallWindow.svelte

4. Attach/Detach de Tracks Remotos

Problema Identificado

  • Tracks remotos não eram anexados corretamente aos elementos de vídeo/áudio
  • Não havia tratamento específico para áudio vs vídeo

Correção Implementada

function adicionarTrackRemoto(track: JitsiTrack): void {
  const participantId = track.getParticipantId();
  const trackType = track.getType();
  
  if (trackType === 'audio') {
    // Criar elemento de áudio invisível
    const audioElement = document.createElement('audio');
    audioElement.id = `remote-audio-${participantId}`;
    audioElement.autoplay = true;
    track.attach(audioElement);
    videoContainer.appendChild(audioElement);
  } else if (trackType === 'video') {
    // Criar elemento de vídeo
    const videoElement = document.createElement('video');
    videoElement.id = `remote-video-${participantId}`;
    videoElement.autoplay = true;
    track.attach(videoElement);
    videoContainer.appendChild(videoElement);
  }
}

Arquivo modificado:

  • apps/web/src/lib/components/call/CallWindow.svelte

5. Controles de Áudio e Vídeo

Problema Identificado

  • Os métodos handleToggleAudio e handleToggleVideo não criavam novos tracks quando necessário
  • Não atualizavam corretamente o estado dos tracks locais

Correção Implementada

  • Implementada lógica para criar tracks se não existirem
  • Atualização correta do estado dos tracks (mute/unmute)
  • Sincronização com o backend quando anfitrião
  • Anexar/desanexar tracks ao vídeo local corretamente

Arquivo modificado:

  • apps/web/src/lib/components/call/CallWindow.svelte

6. Tratamento de Erros

Problema Identificado

  • Uso de alert() para erros (não amigável)
  • Falta de mensagens de erro claras

Correção Implementada

  • Implementado sistema de tratamento de erros com ErrorModal
  • Integrado com traduzirErro() para mensagens amigáveis
  • Adicionado estado de erro no componente:
    let showErrorModal = $state(false);
    let errorTitle = $state('Erro na Chamada');
    let errorMessage = $state('');
    let errorDetails = $state<string | undefined>(undefined);
    

Arquivos modificados:

  • apps/web/src/lib/components/call/CallWindow.svelte
  • Integração com apps/web/src/lib/utils/erroHelpers.ts

7. Inicialização do Jitsi Meet JS

Problema Identificado

  • Configuração básica do Jitsi pode estar incompleta
  • Nível de log muito restritivo

Correção Implementada

JitsiMeetJS.init({
  disableAudioLevels: false, // Habilitado para melhor qualidade
  disableSimulcast: false,
  enableWindowOnErrorHandler: true,
  enableRemb: true, // REMB para controle de bitrate
  enableTcc: true,  // TCC para controle de congestionamento
  disableThirdPartyRequests: false
});

JitsiMeetJS.setLogLevel(JitsiMeetJS.constants.logLevels.INFO); // Mais verboso para debug

Arquivo modificado:

  • apps/web/src/lib/components/call/CallWindow.svelte

8. UI/UX Melhorias

Implementado

  • Indicador de conexão durante estabelecimento da chamada
  • Mensagem de "Conectando..." enquanto não há conexão estabelecida
  • Tratamento visual adequado de estados de conexão

Arquivo modificado:

  • apps/web/src/lib/components/call/CallWindow.svelte

9. Eventos da Conferência

Adicionado

  • CONFERENCE_JOINED: Criar tracks locais após entrar
  • CONFERENCE_LEFT: Limpar tracks ao sair
  • Melhor tratamento de TRACK_ADDED e TRACK_REMOVED

Arquivo modificado:

  • apps/web/src/lib/components/call/CallWindow.svelte

10. Correção de Interfaces TypeScript

Adicionado

  • Método addTrack() na interface JitsiConference
  • Melhor tipagem de JitsiTrack com propriedade track: MediaStreamTrack

Arquivo modificado:

  • apps/web/src/lib/components/call/CallWindow.svelte

Configuração Necessária

Variáveis de Ambiente (.env)

# Jitsi Meet Configuration (Docker Local)
VITE_JITSI_DOMAIN=localhost:8443
VITE_JITSI_APP_ID=sgse-app
VITE_JITSI_ROOM_PREFIX=sgse
VITE_JITSI_USE_HTTPS=true

Nota: Para Docker Jitsi local, geralmente usa-se HTTPS na porta 8443.


Verificações Necessárias

1. Docker Jitsi Rodando

docker ps | grep jitsi

2. Porta 8443 Acessível

curl -k https://localhost:8443

3. Permissões do Navegador

  • Microfone deve estar permitido
  • Câmera deve estar permitida (para chamadas de vídeo)

4. Logs do Navegador

  • Abrir DevTools (F12)
  • Verificar Console para erros de conexão
  • Verificar Network para erros de rede

Próximos Passos (Se Necessário)

  1. Testar conectividade - Verificar se o servidor Jitsi responde corretamente
  2. Ajustar configuração de rede - Se houver problemas de firewall ou CORS
  3. Configurar STUN/TURN - Para conexões através de NAT (se necessário)
  4. Otimizar qualidade - Ajustar bitrates e resoluções conforme necessário

Status

Todas as correções foram implementadas Código sem erros de lint Tratamento de erros adequado Interfaces TypeScript corretas Gerenciamento de recursos adequado


Data: $(date) Versão: 1.0.0