Aller au contenu

Réunions et transcription

Control Center peut enregistrer un appel et vous remettre un compte rendu propre — un résumé, des tâches et des décisions — grâce à la reconnaissance vocale et à la séparation des locuteurs qui s’exécutent sur votre propre matériel. Pensez à Granola, mais auto-hébergé et relié au même espace de travail que celui où vivent vos agents.

Une réunion est une séance enregistrée et transcrite. Ce n’est pas la même chose qu’un événement de calendrier : un événement est un engagement planifié synchronisé depuis Google, tandis qu’une réunion est quelque chose que vous avez réellement enregistré. Les deux peuvent être liés, puisque vous pouvez démarrer un enregistrement depuis un événement, mais ils restent des enregistrements distincts.

Chaque réunion est rattachée à un espace de travail, comme tout le reste dans Control Center. Les réunions enregistrées dans un espace de travail ne remontent jamais dans un autre.

« Sur l’appareil » est la bonne intuition, mais pas le bon mot. Le client capte l’audio et diffuse des trames PCM16 à 16 kHz vers la machine qui exécute cc_server. Cet hôte fait tout le reste : il écrit les fichiers WAV par canal sous <dataDir>/meetings/<meetingId>/, transcrit dans un isolat de worker, filtre l’écho et effectue la diarisation après coup. Sur un poste de travail autonome, cet hôte est la même machine. Dirigé vers un serveur distant, ce n’est plus le cas — donc « rien ne quitte mon ordinateur portable » n’est vrai que lorsque le serveur est votre ordinateur portable.

Il existe une exception supplémentaire, et c’est la plus importante.

Tout ce qui précède le résumé — capture, transcription, annulation d’écho, diarisation, correspondance des empreintes vocales — s’exécute sur le serveur sans aucun appel réseau.

Les modèles d’embedding, de diarisation et de reconnaissance vocale (ASR) sont installés de force au premier démarrage (sauf en mode démo), de sorte que la séparation des locuteurs et l’enregistrement sont disponibles sans passer par les paramètres. L’ASR reste sélectionnable — elle pèse plusieurs centaines de mégaoctets et quatre variantes figurent dans le sélecteur. La reconnaissance vocale nécessite tout de même un redémarrage après ce premier téléchargement, car le transcripteur résout son modèle avant que la récupération puisse se terminer.

Les quatre entrées du sélecteur, qui diffèrent par la taille, la couverture linguistique et la précision :

  • Parakeet TDT 0.6B v3 — multilingue, la valeur par défaut recommandée (~600 Mo)
  • Parakeet TDT 0.6B v2 — anglais (~480 Mo)
  • Whisper large-v3-turbo — multilingue (~626 Mo)
  • Whisper base.en — anglais uniquement, la petite valeur par défaut historique (~198 Mo)

Les modèles sont les seuls artefacts que le serveur récupère à l’exécution ; toutes les bibliothèques natives sont livrées dans le paquet.

Une réunion enregistre deux canaux audio à la fois :

  • Vous (« moi ») : votre microphone.
  • Les autres (« eux ») : la sortie audio de la réunion, captée par un bouclage sans pilote — captures Core Audio de processus et de périphérique sur macOS, bouclage WASAPI sur Windows, moniteur PipeWire / PulseAudio sur Linux.

Comme les deux canaux sont captés séparément, la transcription est attribuée par locuteur dès le départ : vos paroles portent l’étiquette me, et toutes les personnes en ligne portent l’étiquette them.

Votre propre voix s’infiltre de la sortie système vers le micro et serait sinon transcrite deux fois. Deux filtres l’empêchent. Au niveau du signal, l’AEC3 s’exécute sur chaque enregistrement en mode distant et est obligatoire — si la bibliothèque AEC native ne peut pas se charger, l’enregistrement refuse de démarrer plutôt que de diffuser en silence un micro pollué par l’écho. (Le mode en personne n’a aucune référence de bout distant à annuler, l’AEC y est donc un passe-système.) Par-dessus, un filtre d’écho textuel côté hôte s’exécute sur toutes les plateformes.

Tout traitement du microphone au niveau du système d’exploitation est délibérément désactivé. Activer l’annulation d’écho ou le gain automatique de la plateforme sur macOS fait basculer le micro vers Voice Processing I/O, ce qui, dans cette version, a mis hors service à la fois le micro et la capture de l’audio système.

Pendant l’enregistrement, l’audio est décodé par fenêtres glissantes — découpées sur un court silence de fin, ou à une longueur de fenêtre maximale — en dehors du fil de l’interface. Chaque fenêtre devient un segment de transcription étiqueté par locuteur, avec des décalages en millisecondes.

Les fenêtres qui n’ont jamais dépassé un seuil RMS sont ignorées sans être décodées du tout, car un modèle vocal rend le silence sous forme de jetons non vocaux hallucinés et ce décodage gaspille du CPU. Conséquence pratique : un locuteur constamment très discret ne produit aucune transcription. Si quelqu’un revient sans transcription, vérifiez son niveau d’entrée avant d’accuser le modèle.

Après l’arrêt, la diarisation s’exécute hors ligne sur l’enregistrement et sépare le canal distant en locuteurs individuels (Person 1, Person 2, …) que vous pouvez renommer. Le nombre de locuteurs est déduit d’un seuil de regroupement, et non d’un nombre que vous définissez — il s’agit donc d’un artefact de seuil, et un locuteur discret ou qui se chevauche peut être fusionné avec un voisin. La transcription est rendue sous forme de lignes [mm:ss] SPEAKER: text.

Renommer un locuteur fait plus qu’étiqueter une transcription. Control Center peut enregistrer l’empreinte vocale du locuteur sous forme de profil vocal, afin de le reconnaître automatiquement lors des réunions suivantes. Lorsque vous nommez un locuteur issu de la diarisation, il vous est demandé si vous voulez enregistrer l’empreinte vocale ; si vous le faites, elle est fusionnée dans un centroïde cumulatif associé à ce nom et comparée aux nouveaux locuteurs par similarité cosinus, de sorte que la même personne réapparaît avec son nom la prochaine fois sans que vous ayez à la réétiqueter.

Les profils vocaux sont rattachés à l’espace de travail et ne franchissent jamais la frontière. Gérez-les dans Paramètres → Espace de travail → Réunions. Renommer un locuteur qui avait déjà été enregistré désinscrit l’ancien nom et propose d’inscrire le nouveau ; supprimer un profil supprime l’empreinte vocale stockée, mais laisse intacts les noms déjà appliqués aux réunions passées.

À l’arrêt d’un enregistrement, le serveur publie un MeetingRecordingStopped événement de domaine. Le modèle de pipeline intégré meeting_summary est déclenché par cet événement. L’enregistreur ne l’attend pas ; la réunion traverse simplement son cycle de vie de statuts :

recording → processing → done

L’agent de synthèse reçoit le titre, vos notes brutes prises en direct et la transcription, puis renvoie du JSON structuré. Les sections qu’il rédige dépendent du modèle de notes de réunion actif de l’espace de travail (Paramètres → Espace de travail → Réunions) ; le modèle actif s’applique aux nouveaux résumés et aux relances. Les étapes de persistance du pipeline écrivent ensuite ce JSON dans des lignes distinctes :

  • enhancedNotes et summary → les notes de la réunion
  • chaque tâche → une ligne MeetingActionItem (contenu, responsable, lien de ticket facultatif)
  • chaque décision → une ligne MeetingDecision

Les tâches et les décisions ne sont jamais extraites d’un markdown libre, uniquement des tableaux structurés de l’agent. Si une exécution ne produit aucune sortie structurée, les étapes de persistance sont ignorées et la transcription brute est conservée comme solution de repli, de sorte que vous ne perdez jamais la trace de l’enregistrement. Rien dans le pipeline ne marque la réunion comme done — un unique réconciliateur s’en charge à partir de l’événement terminal de l’exécution, de sorte qu’une étape voisine qui échoue ne peut pas laisser en plan une réunion à moitié écrite qui semble déjà terminée.

Surface Ce qu’elle affiche
/meetings La liste des réunions, avec le nombre de tâches et de décisions
/meetings/record L’interface d’enregistrement en direct : vos notes d’un côté, la transcription en direct de l’autre
/meetings/:meetingId Le détail d’une réunion : les onglets Notes, Transcription, Tâches et Décisions
Paramètres → Espace de travail → Réunions Modèles de notes et profils vocaux enregistrés pour cet espace de travail

La capture fonctionne sans pilote sur les trois plateformes de bureau (captures Core Audio sur macOS, WASAPI sur Windows, PipeWire sur Linux).

Le client web enregistre lui aussi, ce que le reste de cette page, centrée sur le bureau, peut masquer : le navigateur accède à votre micro via getUserMedia et à l’audio de la réunion via getDisplayMedia (partage d’écran), réduit l’échantillonnage à 16 kHz en PCM16 et diffuse vers le même hôte. Trois réserves s’appliquent ici :

  • La surface partagée doit comporter une piste audio. Le partage plein écran de Safari, de Firefox et de macOS n’en fournit aucune et l’enregistrement refuse de démarrer.
  • Il n’y a pas d’AEC3 natif. L’annulation d’écho propre au navigateur est demandée sur le micro ; le filtre d’écho textuel côté hôte s’exécute toujours. L’interface affiche un indicateur de niveau d’entrée alimenté par le PCM du micro.
  • Relancer le résumé et annuler le traitement ne sont disponibles que sur le bureau.

L’action Enregistrer et lier du calendrier n’est disponible que sur le bureau et l’indique clairement sur le web, même si le flux d’enregistrement propre à l’écran des réunions y fonctionne.