Architecture et conception de Hush Meet
┌─────────────────────────────────────────────────────┐
│ Extension Chrome (Manifest V3) │
│ │
│ ┌──────────────┐ ┌───────────────────────────┐ │
│ │ Interface Popup │ │ Content Script │ │
│ │ (React) │ │ (meet.google.com) │ │
│ │ │ │ │ │
│ │ - Bascule │ │ ┌────────────────────┐ │ │
│ │ - Niveau │◄───►│ │ Analyseur Audio │ │ │
│ │ - Réglages │ │ │ (Web Audio API) │ │ │
│ │ │ │ └────────┬───────────┘ │ │
│ └──────────────┘ │ │ │ │
│ ▲ │ ┌────────▼───────────┐ │ │
│ │ │ │ Machine à états │ │ │
│ │ │ │ IDLE → MUTED → │ │ │
│ │ │ │ SPEAKING → GRACE │ │ │
│ │ │ └────────┬───────────┘ │ │
│ │ │ │ │ │
│ │ │ ┌────────▼───────────┐ │ │
│ │ │ │ Contrôleur Mute │ │ │
│ │ │ │ (manipulation DOM)│ │ │
│ │ │ └────────────────────┘ │ │
│ │ └───────────────────────────┘ │
│ │ │
│ └─── Chrome Storage API (sync config/état)─┘
│ │
└─────────────────────────────────────────────────────┘
src/
├── constants.ts # Constantes, modes, seuils, clés de stockage
├── messages.ts # Messages i18n (EN/JA)
├── i18n.ts # Gestion des locales
├── manifest.ts # Définition du manifeste de l'extension Chrome
├── background/
│ └── service-worker.ts # Service Worker (lanceur de jeux, etc.)
├── content/
│ └── index.ts # Content Script (machine à états, contrôle des modes, raccourcis)
└── popup/
├── index.html # HTML d'entrée du popup
├── main.tsx # Point de montage React
├── Popup.tsx # Composant UI du popup
├── popup.css # Styles
├── Equalizer.tsx # Analyseur de spectre
├── ThemeSwitcher.tsx # Sélecteur de thème
├── LocaleSwitcher.tsx# Sélecteur de langue
└── GameLauncher.tsx # Lanceur de mini-jeux
src/content/index.ts)Ce script est injecté dans la page Google Meet. Ses principales responsabilités sont :
Utilise l'API Web Audio AnalyserNode pour mesurer le volume d'entrée du microphone en temps réel.
getUserMedia() → AudioContext → MediaStreamSource → AnalyserNode
│
getFloatTimeDomainData()
│
Calcul RMS (Root Mean Square)
Paramètres de configuration :
| Paramètre | Valeur | Description |
|---|---|---|
fftSize |
512 | Taille de la fenêtre FFT |
smoothingTimeConstant |
0.3 | Coefficient de lissage temporel |
echoCancellation |
true | Activer l'annulation d'écho |
noiseSuppression |
false | Suppression du bruit désactivée (pour la précision du VAD) |
Une machine à états finis à 5 états gère l'état de la parole.
IDLE ──(mode autre que Off sélectionné)──► MUTED ──(volume > speechThreshold)──► UNMUTING ──► SPEAKING
▲ │
│ (volume < silenceThreshold)
│ │
└──(graceTimer expiré)── GRACE ◄─────────────────┘
│
(volume > silenceThreshold)
│
▼
SPEAKING
* Si l'utilisateur bascule manuellement le microphone Meet, le mode reste le même et seul l'état suit.
| État | Description | Action Meet |
|---|---|---|
| IDLE | Mode Off ou non initialisé | Aucune |
| MUTED | Silence détecté → micro coupé | Couper le micro |
| UNMUTING | Parole détectée → réactivation | Réactiver le micro |
| SPEAKING | En train de parler | Aucune |
| GRACE | Fin de parole → période de grâce | Aucune |
Quatre modes contrôlent le comportement des transitions d'état. Off est le mode de contrôle désactivé.
| Mode | Réactivation | Coupure | Raccourci |
|---|---|---|---|
| Off | Aucune | Aucune | Désactivé |
| Auto | Automatique à la détection vocale | Automatique au silence | Bascule |
| Auto-Off | Manuel / raccourci | Automatique au silence | Bascule |
| Push-to-Talk | Tant que la touche est enfoncée | Touche relâchée → Grâce → Coupure | Maintenir |
Fournit un raccourci clavier personnalisable (par défaut : Ctrl+Shift+M).
La touche de raccourci peut être librement modifiée depuis les réglages du popup.
Des seuils différents pour la réactivation et la coupure empêchent le chattering (basculement fréquent).
speechThreshold (début de parole) = 0.025 (par défaut)
silenceThreshold (détection silence) = speechThreshold × 0.5 = 0.0125
Volume
▲
│ ┄┄┄┄┄┄┄┄┄ speechThreshold (0.025) ┄┄┄┄ ← Réactivation si dépassé
│
│ ┄┄┄┄┄┄┄┄┄ silenceThreshold (0.0125) ┄┄ ← Période de grâce si en dessous
│
└──────────────────────────────────────────► Temps
Détecte le bouton mute de Google Meet à l'aide de plusieurs stratégies :
aria-label (prend en charge le japonais et l'anglais)data-tooltipCtrl+D
L'état mute est déterminé à partir de l'attribut data-is-muted ou du contenu textuel de l'aria-label.
src/popup/)Une interface de réglages construite avec React 19. Synchronise l'état avec le Content Script en temps réel via l'API Chrome Storage.
speechThreshold (0.005–0.25) — sauvegardé par mode
gracePeriod (500ms–4000ms) — sauvegardé par mode
Popup → Chrome Storage → Content Script
│ │
│ hushMeetConfig: object │ (réglages sensibilité/période de grâce)
│ hushMeetMode: string │ (mode de fonctionnement)
│ hushMeetShortcutKey: str │ (touche de raccourci)
│ │
│ ▼
│ Content Script → Chrome Storage → Popup
│ │
│ │ hushMeetState: string (état actuel)
│ │ hushMeetLevel: number (niveau de volume)
│ │ hushMeetSpectrum: array (spectre)
└────────────────────────────┘
Le Popup et le Content Script ne communiquent pas directement ; ils communiquent de manière bidirectionnelle via les événements de changement de l'API Chrome Storage.
| Outil | Version | Objectif |
|---|---|---|
| Vite+ | toolchain | Gestion des dépendances, build, tests, validation |
| Vite | 8.x | Infrastructure de build interne |
| CRXJS Vite Plugin | 2.x | HMR pour extension Chrome et génération de manifeste |
| React | 19.x | Popup UI |
| TypeScript | 5.9.x | Sécurité des types |
| Commande | Description |
|---|---|
vp install |
Installer les dépendances |
vp build |
Build de production |
vp test |
Exécuter les tests |
vp check |
formatage / lint / vérification de types |