← 홈으로 돌아가기

기술 문서

Hush Meet의 아키텍처 및 설계

아키텍처 개요

┌─────────────────────────────────────────────────────┐
│  Chrome 확장 프로그램 (Manifest V3)                     │
│                                                     │
│  ┌──────────────┐     ┌───────────────────────────┐ │
│  │   팝업 UI   │     │     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          # 콘텐츠 스크립트 (상태 머신, 모드 제어, 단축키)
└── popup/
    ├── index.html        # 팝업 엔트리 HTML
    ├── main.tsx          # React 마운트
    ├── Popup.tsx         # 팝업 UI 컴포넌트
    ├── 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 ──(Off 이외의 모드 선택)──► MUTED ──(볼륨 > speechThreshold)──► UNMUTING ──► SPEAKING
                     ▲                                                │
                     │                              (볼륨 < silenceThreshold)
                     │                                                │
                     └──(graceTimer 만료)── GRACE ◄────────────────────┘
                                                │
                                         (볼륨 > silenceThreshold)
                                                │
                                                ▼
                                            SPEAKING

* 사용자가 수동으로 Meet 마이크를 전환하면 모드는 유지되고 상태만 따라갑니다.
상태 설명 Meet 동작
IDLE Off 모드 또는 미초기화 없음
MUTED 무음 감지 → 음소거 음소거
UNMUTING 음성 감지 → 음소거 해제 중 음소거 해제
SPEAKING 현재 발화 중 없음
GRACE 발화 종료 → 유예 기간 없음

1.3 동작 모드

4가지 모드가 상태 전환 동작을 제어합니다. Off는 제어 비활성화 모드입니다.

모드 음소거 해제 음소거 단축키
Off 없음 없음 비활성화
Auto 음성 감지 시 자동 무음 시 자동 토글
Auto-Off 수동 / 단축키 무음 시 자동 토글
Push-to-Talk 키를 누르고 있는 동안 키 놓기 → 유예 → 음소거 홀드

1.4 단축키

사용자 지정 가능한 키보드 단축키를 제공합니다 (기본값: Ctrl+Shift+M).

단축키는 팝업 설정에서 자유롭게 변경할 수 있습니다.

1.5 비대칭 임계값 설계

음소거 해제와 음소거에 서로 다른 임계값을 사용하여 채터링(빈번한 전환)을 방지합니다.

speechThreshold (발화 시작)     = 0.025  (기본값)
silenceThreshold (무음 판정)   = speechThreshold × 0.5 = 0.0125

  볼륨
   ▲
   │  ┄┄┄┄┄┄┄┄┄ speechThreshold (0.025) ┄┄┄┄  ← 초과 시 음소거 해제
   │
   │  ┄┄┄┄┄┄┄┄┄ silenceThreshold (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로 구축된 설정 UI입니다. Chrome Storage API를 통해 콘텐츠 스크립트와 실시간으로 상태를 동기화합니다.

데이터 흐름

Popup → Chrome Storage → Content Script
  │                            │
  │  hushMeetConfig: object    │  (감도/유예 기간 설정)
  │  hushMeetMode: string      │  (동작 모드)
  │  hushMeetShortcutKey: str  │  (단축키)
  │                            │
  │                            ▼
  │                      Content Script → Chrome Storage → Popup
  │                            │
  │                            │  hushMeetState: string  (현재 상태)
  │                            │  hushMeetLevel: number  (볼륨 레벨)
  │                            │  hushMeetSpectrum: array (스펙트럼)
  └────────────────────────────┘

팝업과 콘텐츠 스크립트는 직접 통신하지 않으며, 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 포맷 / 린트 / 타입 체크

알려진 제한 사항

향후 개선 사항