Files
Meeting_Assistant/openspec/changes/archive/2025-12-22-add-audio-device-selector/design.md
egg e7a06e2b8f chore: Archive all pending OpenSpec proposals
Force archive the following proposals:
- add-audio-device-selector (complete)
- add-embedded-backend-packaging (19/26 tasks)
- add-flexible-deployment-options (20/21 tasks)

New specs created:
- audio-device-management (7 requirements)
- embedded-backend (8 requirements)

Updated specs:
- transcription (+2 requirements for model download progress)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 08:44:04 +08:00

5.3 KiB
Raw Blame History

Design: add-audio-device-selector

Architecture Overview

Component Structure

meeting-detail.html
├── Audio Device Panel (新增)
│   ├── Device Selector (dropdown)
│   ├── Volume Meter (canvas/div bars)
│   ├── Test Controls
│   │   ├── Start Test Button
│   │   ├── Stop Test Button
│   │   └── Play Test Button
│   └── Status Indicator
└── Existing Recording Controls
    └── Uses selected device from panel

Data Flow

User selects device → Update localStorage → Update AudioContext
                                         → Start volume monitoring
                                         → Enable test recording

Test Recording Flow:
Start Test → getUserMedia(selected device) → MediaRecorder → Blob
Play Test → Audio element → Play blob URL

Main Recording Flow:
Start Recording → Read selected device from state
               → getUserMedia(selected device)
               → Existing transcription flow

Technical Decisions

TD-1: Volume Meter Implementation

Options Considered:

  1. Web Audio API AnalyserNode - Real-time frequency/amplitude analysis
  2. MediaRecorder + periodic sampling - Sample audio levels periodically
  3. CSS-only animation - Fake animation without real audio data

Decision: Web Audio API AnalyserNode

  • Provides accurate real-time audio level data
  • Low latency visualization
  • Standard browser API, well-supported in Electron

TD-2: Device Preference Storage

Options Considered:

  1. localStorage - Simple key-value storage
  2. config.json - App configuration file
  3. Backend database - Per-user settings

Decision: localStorage

  • No backend changes required
  • Immediate persistence
  • Per-device settings (user may use different mics on different computers)

TD-3: Test Recording Duration

Decision: 5 seconds fixed duration

  • Long enough to verify audio quality
  • Short enough to not waste time
  • Auto-stop prevents forgotten recordings

TD-4: UI Placement

Options Considered:

  1. Modal dialog - Opens on demand
  2. Collapsible panel - Always visible but can be collapsed
  3. Settings page - Separate page for audio settings

Decision: Collapsible panel in meeting-detail page

  • Quick access before recording
  • No page navigation needed
  • Can be collapsed when not needed

UI Mockup

┌─────────────────────────────────────────────────────────┐
│ Audio Device Settings                            [▼]    │
├─────────────────────────────────────────────────────────┤
│ Microphone: [▼ Realtek Microphone (Realtek Audio) ▼]    │
│                                                         │
│ Input Level: ████████░░░░░░░░░░░░ 45%                  │
│                                                         │
│ [🎤 Test Recording]  [▶️ Play Test]  Status: Ready      │
│                                                         │
│  Click "Test Recording" to verify your microphone    │
└─────────────────────────────────────────────────────────┘

State Management

Audio Device State

const audioDeviceState = {
  availableDevices: [],        // Array of MediaDeviceInfo
  selectedDeviceId: null,      // Selected device ID or null for default
  isMonitoring: false,         // Volume meter active
  currentLevel: 0,             // Current audio level 0-100
  testRecording: null,         // Blob of test recording
  testState: 'idle'            // 'idle' | 'recording' | 'playing'
};

localStorage Keys

  • audioDevice.selectedId - Last selected device ID
  • audioDevice.lastUsedLabel - Device label for display fallback

Integration Points

With Existing Recording

  1. startRecording() will read selectedDeviceId from state
  2. If no device selected, use current auto-selection logic
  3. If selected device unavailable, show error and prompt reselection

IPC Considerations

  • No new IPC handlers needed
  • All audio device operations happen in renderer process
  • Uses existing navigator.mediaDevices API

Error Handling

Error User Message Recovery
No devices found "未偵測到麥克風,請連接麥克風後重試" Refresh device list
Device disconnected "選擇的麥克風已斷開連接" Auto-switch to default
Permission denied "麥克風權限被拒絕,請在系統設定中允許" Show permission guide
Device busy "麥克風正被其他應用程式使用" Retry button

Testing Strategy

Manual Testing

  1. Connect multiple microphones
  2. Verify all appear in dropdown
  3. Select each and verify volume meter responds
  4. Record and play test audio for each
  5. Unplug device during use and verify error handling
  6. Restart app and verify saved preference loads

Automated Testing (Future)

  • Mock navigator.mediaDevices for unit tests
  • Test device switching logic
  • Test localStorage persistence