Les briques LiveKit
1) Les briques LiveKit (en 30s)
- SFU (Selective Forwarding Unit) : un serveur relai WebRTC qui reçoit vos flux (caméra, micro, data) et les redirige vers les autres participants sans transcoder (latence très faible).
- Room / Participant / Track : vous créez une room, chaque client rejoint comme participant et “publie” des tracks (video, audio, data). Les autres “s’abonnent”.
- Cloud ou Self-host : soit vous utilisez LiveKit Cloud, soit vous déployez le serveur open-source (Docker/K8s).
- JWT d’accès : votre backend émet un AccessToken (signé avec API Key/Secret LiveKit) pour autoriser chaque client à rejoindre une room.
2) Flux typique (de bout en bout)
- Backend (Express/FastAPI) reçoit “je veux rejoindre la room X”.
- Il crée un JWT LiveKit (rôle, room, durée), et le renvoie au client.
- Client React : getUserMedia → Room.connect(serverUrl, token) → publie la piste vidéo (et éventuellement audio, data channel).
- Bot serveur (optionnel) rejoint la même room (SDK serveur) et s’abonne à la piste vidéo.
-
Le bot pousse les frames au moteur IA :
- Option A : ouvre une session OpenAI Realtime (WebRTC/WebSocket), y envoie les frames (ou échantillons), récupère le raisonnement + outils (appel RAG, Odoo…).
- Option B : envoie les frames à votre serveur d’inférence (PyTorch/TensorRT) qui renvoie (classe, bbox, score) → puis votre backend interroge le RAG.
- La réponse (diagnostic/étapes/sources) revient via data channel ou message REST → le client l’affiche (et peut envoyer liens, images, etc.).
- (Option) Egress pour enregistrer ou sortir le flux (MP4/S3) ; Ingress si vous devez ingérer un flux externe (RTMP/WebRTC).
3) Schéma ultra-simple (qui parle)
flowchart LR ClientReact[[Client React]] -- WebRTC (token) --> LiveKit[(LiveKit SFU)] Bot[Bot Serveur] -- WebRTC --> LiveKit LiveKit -- forward tracks --> Bot Bot -- frames / metadata --> IA[OpenAI Realtime ou Serveur d'inférence] IA -- résultat structuré --> Bot Bot -- DataChannel / REST --> ClientReact Bot -- RAG query --> VectorDB[(pgvector/Qdrant)]
4) Exemples minimalistes (copier-coller)
A. Backend : émettre un token (Node/Express)
import express from "express"; import { AccessToken } from "livekit-server-sdk"; const app = express(); app.get("/token", (req, res) => { const roomName = req.query.room as string; // ex: "agro-phytopatho" const identity = req.query.user as string; // identifiant étudiant const at = new AccessToken(process.env.LK_API_KEY!, process.env.LK_API_SECRET!, { identity, // unique par user ttl: "1h", }); at.addGrant({ roomJoin: true, room: roomName, canPublish: true, canSubscribe: true }); res.json({ token: at.toJwt() }); }); app.listen(3000);
B. Client React : rejoindre & publier la caméra
import { Room, createLocalVideoTrack } from "livekit-client"; const room = new Room(); const token = await fetch(`/token?room=agro-phytopatho&user=${userId}`).then(r=>r.json()).then(j=>j.token); await room.connect("wss://votre-livekit-host", token); // publier la vidéo (caméra arrière sur mobile si dispo) const cam = await createLocalVideoTrack({ facingMode: "environment" }); await room.localParticipant.publishTrack(cam); // écouter les messages “data channel” (résultats IA/RAG) room.on("dataReceived", (payload, participant, kind) => { const msg = new TextDecoder().decode(payload); // afficher diagnostic / sources / liens });
C. Bot serveur : s’abonner au flux et relayer vers l’IA (pseudo-code)
import { RoomServiceClient } from "livekit-server-sdk"; import LiveKitServerBot from "votre-wrapper-livekit-bot"; const bot = new LiveKitServerBot("wss://votre-livekit-host", BOT_TOKEN); await bot.join("agro-phytopatho"); // à chaque nouveau track vidéo bot.onVideoTrack(async (track) => { for await (const frame of track.frames()) { // 1) Downscale + normaliser // 2) Envoyer vers OpenAI Realtime OU votre modèle const result = await infer(frame); // {species, disease, score, bbox[]} // 3) Si score>=τ => query RAG namespace const answer = await queryRAG(result); // 4) Retour vers le client (data channel) bot.sendData(JSON.stringify(answer)); } });
5) Sécurité & RGPD (pratique)
- On-device par défaut : ne publiez que si l’étudiant opt-in.
- Masquez visages/tiers (segmentation Web) avant publication.
- Limitez ce que le bot retient (uniquement métadonnées utiles + anonymisation).
- JWT courts + rôles (ex. étudiant : publish vidéo / subscribe data ; bot : subscribe vidéo / publish data).
6) Quand choisir LiveKit (vs direct Realtime API) ?
- LiveKit si vous voulez : multi-participants, enregistrement, salles persistantes, scalabilité RTC, data channels fiables, et possibilité d’ajouter d’autres pairs (tuteurs, groupe TP).
- Direct OpenAI Realtime seul : OK pour 1-à-1 simple ; moins flexible pour la topologie (rooms, subscriptions, enregistrements, ingress/egress).
Si vous le souhaitez, je vous fournis un squelette de repo (monorepo) avec :
- apps/web (React + LiveKit client + masque RGPD + UI RAG),
- apps/api (Express : /token, /rag, connecteurs OpenAI/VectorDB),
- apps/bot (bot LiveKit qui relaie vers OpenAI Realtime ou votre moteur PyTorch).