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>
5.3 KiB
5.3 KiB
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:
- Web Audio API AnalyserNode - Real-time frequency/amplitude analysis
- MediaRecorder + periodic sampling - Sample audio levels periodically
- 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:
- localStorage - Simple key-value storage
- config.json - App configuration file
- 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:
- Modal dialog - Opens on demand
- Collapsible panel - Always visible but can be collapsed
- 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 IDaudioDevice.lastUsedLabel- Device label for display fallback
Integration Points
With Existing Recording
startRecording()will readselectedDeviceIdfrom state- If no device selected, use current auto-selection logic
- 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.mediaDevicesAPI
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
- Connect multiple microphones
- Verify all appear in dropdown
- Select each and verify volume meter responds
- Record and play test audio for each
- Unplug device during use and verify error handling
- Restart app and verify saved preference loads
Automated Testing (Future)
- Mock
navigator.mediaDevicesfor unit tests - Test device switching logic
- Test localStorage persistence