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 de sourdine personnalisable (par défaut : Ctrl+Shift+M) plus des raccourcis fixes de mode dans l'onglet Meet : Ctrl+Shift+0 Désactivé, Ctrl+Shift+1 Auto, Ctrl+Shift+2 Auto-Off, Ctrl+Shift+3 Appuyer pour parler.
Le raccourci de sourdine peut être modifié depuis les réglages du popup. Les raccourcis de changement de mode sont fixes.
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 |