Nouveau : setup-helper.js
- Détecte si mkcert est installé
- Installe mkcert automatiquement (Homebrew macOS, curl Linux)
- Installe CA locale (mkcert -install)
- Génère certificats pour localhost + IP réseau
- Détection automatique IP WiFi
Intégration dans main.js :
- Vérifie certificats au démarrage
- Si absents : dialog onboarding + setup auto
- Dialog progress "Configuration en cours..."
- Dialog success avec IP réseau
- Dialog error si échec (fallback manuel)
- Ne démarre serveur que si certificats OK
Expérience utilisateur :
1. Lancer l'app (première fois)
2. Dialog : "Première utilisation, configuration..."
3. Cliquer "Continuer"
4. Attendre 1-2 min (installation mkcert + CA + certificats)
5. Dialog : "Configuration terminée, IP: 192.168.x.x"
6. Serveur démarre automatiquement
Prochaines fois : détection certificats OK → démarre direct
L'utilisateur n'a RIEN à faire manuellement !
Les handlers ipcMain.handle() doivent être définis après app.whenReady()
sinon ipcMain est undefined
Résout: TypeError: Cannot read properties of undefined (reading 'handle')
- Logs LiveKit vont dans stderr (normal pour Go), ne pas traiter comme erreurs
- Transmettre tous les logs au renderer (stdout + stderr)
- Détecter "Serveur prêt" dans stdout pour confirmer démarrage
- Timeout augmenté à 15s avec health check avant de résoudre
- Suppression filtres logs verbeux qui cachaient les messages importants
Résout : serveur tué immédiatement après démarrage
Problème résolu : certificats self-signed bloqués par navigateurs
Solution : mkcert génère certificats automatiquement approuvés
- CA locale installée sur système
- Certificats signés par cette CA
- Navigateurs font confiance automatiquement
- Pas de warnings SSL
- 100% local, pas de cloud/domaine
Nouveau script : setup-certificates.sh
- Installe mkcert (Homebrew/apt)
- Installe CA locale (mkcert -install)
- Détecte IP réseau automatiquement
- Génère certificats localhost + IP + *.local
- Configure server/.env (SSL_CERT, SSL_KEY)
- Configure client/.env (VITE_SERVER_URL)
- Met à jour vite.config.js avec HTTPS
Serveur modifié : server/index.js
- Lit certificats depuis process.env.SSL_CERT/SSL_KEY
- Fallback : ../certs/localhost.pem
- Message erreur si certificats introuvables
Documentation :
- SSL-SETUP.md : guide complet installation manuelle/auto
- SSL-SOLUTION.md : résumé technique
- README.md : ajout étape setup-certificates.sh
Résultat :
- Cadenas vert sur desktop (Chrome/Safari/Firefox)
- WebRTC fonctionne en HTTPS
- Smartphones : accepter certificat une fois (normal)
- Valable 10 ans, pas de renouvellement
Usage : ./setup-certificates.sh (2 minutes)
Ensuite : ./start.sh --dev ou ./start-desktop.sh
- Ajout buffer d'accumulation dans PipeWireBackend (même pattern que CoreAudio)
- Ajout buffer d'accumulation dans JACKBackend
- pw-cat et jack_rec émettent aussi des chunks de taille variable
- Garantit frames fixes (960 samples) sur tous les backends
- Prévient audio haché/robotique sous Linux
Problème:
- Son complètement déformé (clipping massif)
- CoreAudio capture en 32-bit mais traité comme 16-bit
- Mixage additif sans normalisation
Solution:
1. Sox convertit 32→16 bit automatiquement
2. GroupAudioRouter divise gain par nombre de sources
Exemple: 2 inputs → groupe default = gain × 0.5 chacun
Résultat: Aucun clipping détecté, audio propre
- Conversion des routes groupes (GET/POST/PUT/DELETE) pour utiliser configManager
- Suppression de loadConfig() et saveConfig() locales (redondantes)
- Fix: les modifications de groupes sont maintenant persistées correctement
- Les groupes créés/modifiés/supprimés survivent au redémarrage du serveur
- Admin : regroupement des 3 dropdowns cartes son dans une seule section
- Admin : suppression du mode édition pour noms de canaux (directement éditables)
- Admin : unification des boutons de sauvegarde en bas de chaque section
- Admin : routing par hash URL pour persistance des onglets (#groups, #audio, etc.)
- AudioRoutingMatrix : bouton sauvegarde déplacé en bas de la matrice
- AudioRoutingMatrix : dropdowns de gain en nuance de bleu (cohérence visuelle)
- Settings : suppression paramètres inutiles (mode PTT continu, feedback audio non implémenté)
- Settings : conservation uniquement du paramètre vibrations (fonctionnel)
- PTTButton : suppression init mode continu par défaut (redondant avec geste verrouillage)
- PWAInstallPrompt : ajout fond semi-transparent et couleurs hardcodées pour lisibilité
- Admin : fix dropdowns audio qui se réinitialisaient (useRef au lieu de useState pour édition)
LiveKit renvoie Int16Array directement au lieu de Buffer.
Ajout détection Int16Array dans _bufferToFloat32 avec conversion directe.
Ajout logs RMS/dBFS pour diagnostiquer niveau audio.
Problème : LiveKit envoie des frames de 240 samples (5ms @ 48kHz)
mais GroupRouter attend 960 samples (20ms). Cela causait :
- Bruit audio (720 samples de silence ajoutés à chaque frame)
- Latence de plusieurs secondes (buffers qui s'accumulent)
Solution :
- Ajout liveKitFrameAccumulators Map pour chaque groupe
- Accumulation de 4 frames LiveKit (240×4 = 960) avant routing
- Nettoyage logs verbeux dans AudioBridge et GroupAudioRouter
Résultat attendu :
- Audio clair (pas de silence injecté)
- Latence réduite (~20ms au lieu de plusieurs secondes)
LiveKit SDK returns audio data as Uint8Array/ArrayBuffer, not Node.js Buffer.
Added Buffer.from() conversion before readInt16LE operations.
Fixes: TypeError: buffer.readInt16LE is not a function
Permet à l'audio reçu des clients d'être converti en Float32 pour lecture.
Filtrage des logs :
- LIVEKIT_LOG_LEVEL=info au lieu de debug
- Suppression logs DEBUG, signal requests/responses
- Garde uniquement INFO, WARN, ERROR importants
Rend les logs bien plus lisibles pour le debug applicatif.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Problème : participant.trackPublications vide au moment de ParticipantConnected
Solution : écouter RoomEvent.TrackPublished et s'abonner au track audio dès sa publication
Flow : Client connecte → ParticipantConnected → Client publie track → TrackPublished → Souscription
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Problème : RoomEvent.TrackSubscribed ne se déclenchait jamais avec @livekit/rtc-node
Solution :
- Itération manuelle sur participant.trackPublications quand participant se connecte
- Création AudioStream immédiate si track audio disponible
- Factorisation code dans _handleAudioTrack()
Cela devrait permettre de recevoir l'audio des clients PWA.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Ajout de logs pour :
- RoomEvent.TrackPublished : détecte quand un participant publie un track
- RoomEvent.TrackSubscribed : logs plus détaillés avec kind et sid
- Permet de diagnostiquer pourquoi AudioBridge ne reçoit pas les tracks audio
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Correction import et utilisation d'AudioStream :
- Import AudioStream depuis @livekit/rtc-node
- new AudioStream(track, sampleRate, channels) au lieu de new track.AudioStream(...)
Cela devrait permettre la réception des frames audio depuis les clients PWA.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Architecture refactorisée pour supporter plusieurs connexions LiveKit simultanées :
- AudioBridge : Map<groupName, LiveKitClient> au lieu d'un seul client
- AudioBridgeManager : génère un token JWT par groupe avec room dédiée
- Routing audio bidirectionnel par groupe :
* FLUX 1 (carte son → LiveKit) : envoie vers le bon client selon groupName
* FLUX 2 (LiveKit → carte son) : reçoit audio avec groupName correct
- Chaque groupe a sa propre room LiveKit (nom = groupId slugifié)
Fixes l'issue où les clients connectés à "production" ne recevaient pas
l'audio car AudioBridge était connecté uniquement à "main".
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- AudioBridge passe inputTargetDevice et outputTargetDevice à PipeWire
- Fix: PipeWire utilisait targetDevice au lieu de input/outputTargetDevice
- Devrait maintenant démarrer les streams pw-cat correctement
- /usr/bin/pactl au lieu de 'pactl' pour éviter problèmes PATH
- Correction dans getDevices(), getDefaultInputDevice(), getDefaultOutputDevice()
- Fix 'pactl: not found' malgré installation de pulseaudio-utils
- Linux : utilise server/bin/livekit-server (installé par install.sh)
- macOS : utilise livekit-server du PATH (Homebrew)
- Corrige erreur 'livekit-server: not found' sous Linux
- Mode dev : proxy Vite /livekit → ws://localhost:7880 (évite mixed content)
- Mode prod : HTTP direct, pas de HTTPS (auto-hébergé local)
- Détection automatique du mode via import.meta.env.DEV
- En production réelle, HTTPS sera géré par reverse proxy
- Création d'un apiRouter Express pour toutes les routes API
- Routes montées sous /api ET à la racine (rétrocompatibilité)
- QR code corrigé : HTTPS en mode production
- start.sh : affichage URL HTTPS corrigé
- Résout le problème de connexion en mode production
- Ajout .env.production avec VITE_API_URL=. (URLs relatives)
- Le client build utilise maintenant les routes directes (/config au lieu de /api/config)
- Rebuild client avec la bonne configuration pour HTTPS production
- start.sh teste maintenant https://localhost:3000 en production
- Ajout flag -k à curl pour accepter certificat auto-signé
- Correction timeout qui empêchait le démarrage
- Ajout support HTTPS au serveur Express avec certificats auto-signés
- Variable d'environnement ENABLE_HTTPS pour activer/désactiver HTTPS
- start.sh active automatiquement HTTPS en mode production (pas --dev)
- Messages d'aide clarifiés avec URLs HTTPS et avertissement certificat
- WebSocket Audio Levels supporte wss:// en mode HTTPS
Mode dev : HTTPS sur port 5173 (Vite) + HTTP API sur 3000
Mode prod : HTTPS sur port 3000 (Express sert client + API)
- Réinstallation qrcode-terminal dans server/ (utilisé par show-qr.sh)
- Script Node inline dans show-qr.sh qui utilise le package depuis server/
- QR code s'affiche correctement au lancement
- Création show-qr.sh : génère et affiche QR code avant lancement serveur
- Détection auto mode dev/prod pour URL correcte
- start.sh appelle show-qr.sh puis lance serveur silencieusement
- Logs serveur uniquement dans server.log (terminal propre)
- Suppression génération QR dans server/index.js (plus nécessaire)
- Suppression dépendance qrcode-terminal dans server (utilisé via npx dans show-qr.sh)
Selon CLAUDE.md : ne pas créer de fichiers récapitulatifs.
Suppression de CHANGELOG-PORTABLE.md et FEATURES-QR-HTTPS.md.
L'historique git suffit pour le changelog.
README-PORTABLE.md reste (documentation utilisateur).
Utilise 'tee' au lieu de redirection > pour :
- Afficher la sortie serveur dans le terminal (QR code visible)
- Conserver les logs dans server.log
Sans cela, le QR code n'était jamais visible pour l'utilisateur.