--- id: "0151" title: "matrix-client-pc calls LiveKit: 1:1 + grupales, mic/cam/screen" status: pending priority: high created: 2026-05-24 related_flows: ["0010"] related_issues: ["0150", "0152"] dependencies: ["0150"] tags: [matrix, livekit, calls, webrtc, video, audio, screen-share] --- ## Objetivo Llamadas via LiveKit SFU (ya activo en `organic-machine.com:7880-7882`). Backend Go genera JWT con `livekit-server-sdk-go`. Frontend React usa `livekit-client` JS para join room, manejar tracks (mic/cam/screen), UI con tiles participantes, controles. Soporta 1:1 + grupales hasta 16 (limite config actual). ## Tareas 1. Backend Go: - `MatrixService.RequestCallToken(matrixRoomID) -> (token, livekitRoomURL)`. - Mapea Matrix roomID -> LiveKit room name (hash determinista). - Genera JWT con claim `room`, `identity` (matrix userID), `ttl 30min`. - Permisos: `canPublish=true, canSubscribe=true, canPublishData=true`. - Publicar event Matrix `m.call.member` para sincronizar quien esta en call (MSC3401). 2. Frontend React: - Hook `useLiveKitCall(matrixRoomID)`: - Pide token al backend. - Conecta `Room` de `livekit-client`. - Expone participants, tracks, localTracks, state. - Auto-publish microfono on connect (mute default). - Componente `CallPanel`: - Grid tiles participantes (1, 2, 4, 9, 16 layout). - Tile principal con speaker activo (active-speaker detection del SDK). - Controles bottom: mic, cam, screen share, raise hand, leave. - PiP mode: cuando minimizado, tile flotante en esquina. - Boton "Start call" en header del room (icono telefono). - Boton "Join call" si hay call activa (segun `m.call.member` events). - Notifs ring incoming call: audio + desktop notif. 3. Backend ICE/TURN: - Verificar LiveKit config tiene TURN configurado (NAT traversal). Si no, anadir coturn container. 4. Tests: - `e2e/test_call_1to1.sh` — 2 clientes (Wails + Element Web), 30s call, audio+video flow. - `e2e/test_call_screen_share.sh` — compartir pantalla, otro cliente ve el track. - `e2e/test_call_4_participants.sh` — 4 clientes simultaneos, no crash. ## Funciones del registry a crear - `livekit_token_gen_go_infra` — JWT generator con `livekit-server-sdk-go`. - `matrix_call_member_go_infra` — wrapper para publicar/leer `m.call.member` state events. - `useLiveKitCall_ts_ui` — hook React. - `CallPanel_ts_ui` — componente UI completo de call. - `CallTile_ts_ui` — tile individual con video + nombre + speaker indicator. ## Acceptance - [ ] Boton "Start call" en room DM con otro user. - [ ] Otro cliente (Element Web) ve ring + acepta -> 2 tiles con video+audio. - [ ] Mute mic + apagar cam funciona y se refleja en el otro lado. - [ ] Screen share: tile separado aparece para todos los participantes. - [ ] 4 participantes simultaneos sin crash ni audio cortado. - [ ] Hangup limpia recursos (no tracks fantasma, no peer connections abiertas). ## Notas - LiveKit room name: `sha256(matrix_room_id + secret)` truncado a 32 chars. Asi cualquier cliente que conozca el matrix_room_id puede computar el room name (no es secret). - Token TTL 30min, refresh proactivo a los 25min. - Codecs: H.264 + VP8 fallback para compatibilidad navegadores. Audio: Opus 32kbps. - E2EE en calls: LiveKit soporta E2EE simetrico (insertable streams API). TBD para version posterior — flow inicial usa SRTP only (cifrado SFU<->client, no e2e). - Sygnal push para incoming calls: enviar VoIP push con TTL bajo para wake-up moviles (relevante para issue 0158 Android).