← 返回首页

技术文档

Hush Meet 的架构与设计

架构概览

┌─────────────────────────────────────────────────────┐
│  Chrome 扩展程序 (Manifest V3)                     │
│                                                     │
│  ┌──────────────┐     ┌───────────────────────────┐ │
│  │   弹出界面   │     │     Content Script         │ │
│  │  (React)     │     │   (meet.google.com)        │ │
│  │              │     │                            │ │
│  │  - 切换    │     │  ┌────────────────────┐   │ │
│  │  - 音量表     │◄───►│  │  音频分析器    │   │ │
│  │  - 设置  │     │  │  (Web Audio API)   │   │ │
│  │              │     │  └────────┬───────────┘   │ │
│  └──────────────┘     │           │               │ │
│         ▲             │  ┌────────▼───────────┐   │ │
│         │             │  │  状态机     │   │ │
│         │             │  │  IDLE → MUTED →    │   │ │
│         │             │  │  SPEAKING → GRACE  │   │ │
│         │             │  └────────┬───────────┘   │ │
│         │             │           │               │ │
│         │             │  ┌────────▼───────────┐   │ │
│         │             │  │  静音控制器   │   │ │
│         │             │  │  (DOM 操作)│   │ │
│         │             │  └────────────────────┘   │ │
│         │             └───────────────────────────┘ │
│         │                                           │
│         └─── Chrome Storage API (配置/状态同步)─┘
│                                                     │
└─────────────────────────────────────────────────────┘

项目结构

src/
├── constants.ts          # 常量、模式、阈值、存储键
├── messages.ts           # i18n 消息 (EN/JA)
├── i18n.ts               # 语言管理
├── manifest.ts           # Chrome 扩展程序清单定义
├── background/
│   └── service-worker.ts # Service Worker(游戏启动器等)
├── content/
│   └── index.ts          # Content Script(状态机、模式控制、快捷键)
└── popup/
    ├── index.html        # 弹出页面入口 HTML
    ├── main.tsx          # React 挂载
    ├── Popup.tsx         # 弹出界面组件
    ├── popup.css         # 样式
    ├── Equalizer.tsx     # 频谱分析器
    ├── ThemeSwitcher.tsx # 主题切换器
    ├── LocaleSwitcher.tsx# 语言切换器
    └── GameLauncher.tsx  # 小游戏启动器

组件详情

1. Content Script (src/content/index.ts)

此脚本被注入到 Google Meet 页面中。其主要职责包括:

1.1 音频分析引擎

使用 Web Audio API 的 AnalyserNode 实时测量麦克风输入音量。

getUserMedia() → AudioContext → MediaStreamSource → AnalyserNode
                                                          │
                                                    getFloatTimeDomainData()
                                                          │
                                                    RMS(均方根)计算

配置参数:

参数 说明
fftSize 512 FFT 窗口大小
smoothingTimeConstant 0.3 时间平滑系数
echoCancellation true 启用回声消除
noiseSuppression false 关闭噪声抑制(为保证 VAD 准确性)

1.2 状态机

一个包含 5 个状态的有限状态机管理语音状态。

IDLE ──(选择了非关闭模式)──► MUTED ──(音量 > 语音阈值)──► UNMUTING ──► SPEAKING
                     ▲                                                │
                     │                              (音量 < 静音阈值)
                     │                                                │
                     └──(宽限定时器到期)── GRACE ◄────────────────────┘
                                                │
                                         (音量 > 静音阈值)
                                                │
                                                ▼
                                            SPEAKING

* 如果用户手动切换 Meet 麦克风,模式保持不变,仅状态跟随变化。
状态 说明 Meet 操作
IDLE 关闭模式或未初始化
MUTED 检测到静音 → 已静音 静音
UNMUTING 检测到语音 → 正在取消静音 取消静音
SPEAKING 正在讲话
GRACE 讲话结束 → 宽限期

1.3 运行模式

四种模式控制状态转换的行为。关闭模式为禁用控制模式。

模式 取消静音 静音 快捷键
关闭 禁用
自动 检测到语音时自动取消静音 检测到静音时自动静音 切换
自动关闭 手动 / 快捷键 检测到静音时自动静音 切换
Push-to-Talk 按住键时取消静音 松开键 → 宽限期 → 静音 按住

1.4 快捷键

提供可自定义的键盘快捷键(默认:Ctrl+Shift+M)。

快捷键可以在弹出窗口的设置中自由更改。

1.5 非对称阈值设计

取消静音和静音使用不同的阈值,以防止抖动(频繁切换)。

语音阈值(语音开始)    = 0.025(默认)
静音阈值(静音判定)    = 语音阈值 × 0.5 = 0.0125

  音量
   ▲
   │  ┄┄┄┄┄┄┄┄┄ 语音阈值 (0.025) ┄┄┄┄  ← 超过时取消静音
   │
   │  ┄┄┄┄┄┄┄┄┄ 静音阈值 (0.0125) ┄┄  ← 低于时开始宽限期
   │
   └──────────────────────────────────────────► 时间

1.6 静音按钮检测

使用多种策略检测 Google Meet 的静音按钮:

  1. 通过 aria-label 属性搜索(支持日语/英语)
  2. 通过 data-tooltip 属性搜索
  3. 回退方案:模拟 Ctrl+D 键盘快捷键

静音状态通过 data-is-muted 属性或 aria-label 文本内容来判定。

2. Popup UI (src/popup/)

使用 React 19 构建的设置界面。通过 Chrome Storage API 与 Content Script 实时同步状态。

数据流

Popup → Chrome Storage → Content Script
  │                            │
  │  hushMeetConfig: object    │  (灵敏度/宽限期设置)
  │  hushMeetMode: string      │  (运行模式)
  │  hushMeetShortcutKey: str  │  (快捷键)
  │                            │
  │                            ▼
  │                      Content Script → Chrome Storage → Popup
  │                            │
  │                            │  hushMeetState: string  (当前状态)
  │                            │  hushMeetLevel: number  (音量电平)
  │                            │  hushMeetSpectrum: array (频谱)
  └────────────────────────────┘

Popup 和 Content Script 之间不直接通信;它们通过 Chrome Storage API 的变更事件进行双向通信。

构建系统

工具 版本 用途
Vite+ toolchain 依赖管理、构建、测试、验证
Vite 8.x 内部构建基础设施
CRXJS Vite Plugin 2.x Chrome 扩展程序 HMR 和清单生成
React 19.x Popup UI
TypeScript 5.9.x 类型安全

命令

命令 说明
vp install 安装依赖
vp build 生产环境构建
vp test 运行测试
vp check 格式化 / 代码检查 / 类型检查

已知限制

未来改进