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>
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
# 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
|
||||
```javascript
|
||||
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
|
||||
@@ -0,0 +1,45 @@
|
||||
# Proposal: add-audio-device-selector
|
||||
|
||||
## Summary
|
||||
新增音訊設備選擇與驗證功能,讓使用者可以手動選擇麥克風、即時預覽音量、進行收音測試及播放測試錄音。
|
||||
|
||||
## Problem Statement
|
||||
目前系統自動選擇麥克風,使用者無法:
|
||||
1. 查看可用的音訊輸入設備清單
|
||||
2. 手動選擇偏好的麥克風
|
||||
3. 在錄音前確認麥克風是否正常運作
|
||||
4. 測試收音品質
|
||||
|
||||
這導致使用者在錄音失敗時難以診斷問題,也無法在多個麥克風之間切換。
|
||||
|
||||
## Proposed Solution
|
||||
在會議詳情頁面新增音訊設備管理面板,包含:
|
||||
|
||||
1. **設備選擇器**:下拉選單顯示所有可用麥克風
|
||||
2. **音量指示器**:即時顯示麥克風輸入音量(VU meter)
|
||||
3. **收音測試**:錄製 5 秒測試音訊
|
||||
4. **播放測試**:播放剛錄製的測試音訊
|
||||
5. **設備狀態指示**:顯示目前選中設備的連線狀態
|
||||
|
||||
## Scope
|
||||
- **In Scope**:
|
||||
- 前端 UI 元件(設備選擇器、音量計、測試按鈕)
|
||||
- 設備列舉與切換邏輯
|
||||
- 測試錄音與播放功能
|
||||
- 使用者偏好設定儲存(localStorage)
|
||||
|
||||
- **Out of Scope**:
|
||||
- 系統音訊輸出設備選擇
|
||||
- 音訊處理效果(降噪、增益等)
|
||||
- 遠端音訊設備支援
|
||||
|
||||
## Success Criteria
|
||||
- 使用者可以看到所有可用麥克風並選擇一個
|
||||
- 選擇麥克風後可即時看到音量變化
|
||||
- 測試錄音功能可錄製 5 秒音訊並播放
|
||||
- 偏好設定在下次開啟時保留
|
||||
- 錄音功能使用使用者選擇的麥克風
|
||||
|
||||
## Stakeholders
|
||||
- End Users: 會議記錄人員
|
||||
- Developers: 前端開發團隊
|
||||
@@ -0,0 +1,131 @@
|
||||
# audio-device-management Specification Delta
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Audio Device Enumeration
|
||||
The frontend SHALL enumerate and display all available audio input devices.
|
||||
|
||||
#### Scenario: List available devices
|
||||
- **WHEN** user opens meeting detail page
|
||||
- **THEN** system SHALL enumerate all audio input devices
|
||||
- **AND** display them in a dropdown selector
|
||||
- **AND** exclude virtual/system devices like "Stereo Mix"
|
||||
|
||||
#### Scenario: Refresh device list
|
||||
- **WHEN** user clicks refresh button or device is connected/disconnected
|
||||
- **THEN** system SHALL re-enumerate devices
|
||||
- **AND** update dropdown options
|
||||
- **AND** preserve current selection if still available
|
||||
|
||||
#### Scenario: Device label display
|
||||
- **WHEN** devices are listed
|
||||
- **THEN** each device SHALL display its friendly name (label)
|
||||
- **AND** indicate if it's the system default device
|
||||
|
||||
### Requirement: Manual Device Selection
|
||||
The frontend SHALL allow users to manually select their preferred audio input device.
|
||||
|
||||
#### Scenario: Select device from dropdown
|
||||
- **WHEN** user selects a device from dropdown
|
||||
- **THEN** system SHALL update selected device state
|
||||
- **AND** start volume monitoring on new device
|
||||
- **AND** save selection to localStorage
|
||||
|
||||
#### Scenario: Load saved preference
|
||||
- **WHEN** meeting detail page loads
|
||||
- **THEN** system SHALL check localStorage for saved device preference
|
||||
- **AND** if saved device is available, auto-select it
|
||||
- **AND** if saved device unavailable, fall back to system default
|
||||
|
||||
#### Scenario: Selected device unavailable
|
||||
- **WHEN** previously selected device is no longer available
|
||||
- **THEN** system SHALL show warning message
|
||||
- **AND** fall back to system default device
|
||||
- **AND** prompt user to select new device
|
||||
|
||||
### Requirement: Real-time Volume Indicator
|
||||
The frontend SHALL display real-time audio input level from the selected microphone.
|
||||
|
||||
#### Scenario: Display volume meter
|
||||
- **WHEN** a device is selected
|
||||
- **THEN** system SHALL show animated volume meter
|
||||
- **AND** update meter at least 10 times per second
|
||||
- **AND** display level as percentage (0-100%)
|
||||
|
||||
#### Scenario: Volume meter accuracy
|
||||
- **WHEN** user speaks into microphone
|
||||
- **THEN** volume meter SHALL reflect actual audio amplitude
|
||||
- **AND** peak levels SHALL be visually distinct
|
||||
|
||||
#### Scenario: Muted or silent input
|
||||
- **WHEN** no audio input detected for 3 seconds
|
||||
- **THEN** volume meter SHALL show minimal/zero level
|
||||
- **AND** optionally show "No input detected" hint
|
||||
|
||||
### Requirement: Audio Test Recording
|
||||
The frontend SHALL allow users to record a short test audio clip.
|
||||
|
||||
#### Scenario: Start test recording
|
||||
- **WHEN** user clicks "Test Recording" button
|
||||
- **THEN** system SHALL start recording from selected device
|
||||
- **AND** button SHALL change to "Stop" with countdown timer
|
||||
- **AND** recording SHALL auto-stop after 5 seconds
|
||||
|
||||
#### Scenario: Stop test recording
|
||||
- **WHEN** recording reaches 5 seconds or user clicks stop
|
||||
- **THEN** recording SHALL stop
|
||||
- **AND** audio blob SHALL be stored in memory
|
||||
- **AND** "Play Test" button SHALL become enabled
|
||||
|
||||
#### Scenario: Recording indicator
|
||||
- **WHEN** test recording is in progress
|
||||
- **THEN** UI SHALL show recording indicator (pulsing dot)
|
||||
- **AND** remaining time SHALL be displayed
|
||||
|
||||
### Requirement: Test Audio Playback
|
||||
The frontend SHALL allow users to play back their test recording.
|
||||
|
||||
#### Scenario: Play test recording
|
||||
- **WHEN** user clicks "Play Test" button
|
||||
- **THEN** system SHALL play the recorded audio through default output
|
||||
- **AND** button SHALL change to indicate playing state
|
||||
- **AND** playback SHALL stop at end of recording
|
||||
|
||||
#### Scenario: No test recording available
|
||||
- **WHEN** no test recording has been made
|
||||
- **THEN** "Play Test" button SHALL be disabled
|
||||
- **AND** tooltip SHALL indicate "Record a test first"
|
||||
|
||||
### Requirement: Integration with Main Recording
|
||||
The main recording function SHALL use the user-selected audio device.
|
||||
|
||||
#### Scenario: Use selected device for recording
|
||||
- **WHEN** user starts main recording
|
||||
- **THEN** system SHALL use the device selected in audio settings panel
|
||||
- **AND** if no device selected, use auto-selection logic
|
||||
|
||||
#### Scenario: Device changed during recording
|
||||
- **WHEN** user changes device selection while recording
|
||||
- **THEN** change SHALL NOT affect current recording
|
||||
- **AND** new selection SHALL apply to next recording session
|
||||
|
||||
### Requirement: Audio Settings Panel UI
|
||||
The frontend SHALL display audio settings in a collapsible panel.
|
||||
|
||||
#### Scenario: Panel visibility
|
||||
- **WHEN** meeting detail page loads
|
||||
- **THEN** audio settings panel SHALL be visible but collapsible
|
||||
- **AND** panel state (expanded/collapsed) SHALL be saved
|
||||
|
||||
#### Scenario: Panel layout
|
||||
- **WHEN** panel is expanded
|
||||
- **THEN** it SHALL display:
|
||||
- Device dropdown selector
|
||||
- Volume meter visualization
|
||||
- Test recording button
|
||||
- Play test button
|
||||
- Status indicator
|
||||
|
||||
#### Scenario: Compact mode
|
||||
- **WHEN** panel is collapsed
|
||||
- **THEN** it SHALL show only selected device name and expand button
|
||||
@@ -0,0 +1,125 @@
|
||||
# Tasks: add-audio-device-selector
|
||||
|
||||
## Phase 1: Core Device Management
|
||||
|
||||
### Task 1.1: Add Audio Settings Panel HTML Structure
|
||||
- [x] Add collapsible panel container in meeting-detail.html
|
||||
- [x] Add device dropdown selector element
|
||||
- [x] Add volume meter container (canvas or div bars)
|
||||
- [x] Add test recording/playback buttons
|
||||
- [x] Add status indicator element
|
||||
- **Validation**: Panel renders correctly, all elements visible
|
||||
|
||||
### Task 1.2: Implement Device Enumeration
|
||||
- [x] Create `enumerateAudioDevices()` function
|
||||
- [x] Filter out virtual devices (Stereo Mix)
|
||||
- [x] Populate dropdown with device labels
|
||||
- [x] Mark default device in dropdown
|
||||
- [x] Add device change event listener for hot-plug support
|
||||
- **Validation**: All connected microphones appear in dropdown
|
||||
|
||||
### Task 1.3: Implement Device Selection Logic
|
||||
- [x] Create `selectAudioDevice(deviceId)` function
|
||||
- [x] Stop existing audio context when switching
|
||||
- [x] Create new AudioContext with selected device
|
||||
- [x] Save selection to localStorage
|
||||
- [x] Handle device unavailable errors
|
||||
- **Validation**: Selecting device updates state, persists after refresh
|
||||
|
||||
## Phase 2: Volume Monitoring
|
||||
|
||||
### Task 2.1: Implement Volume Meter
|
||||
- [x] Create AudioContext and AnalyserNode
|
||||
- [x] Connect selected device to analyser
|
||||
- [x] Create volume calculation function (RMS or peak)
|
||||
- [x] Implement requestAnimationFrame loop for updates
|
||||
- [x] Render volume level as visual bar
|
||||
- **Validation**: Meter responds to voice input, updates smoothly
|
||||
|
||||
### Task 2.2: Volume Meter Styling
|
||||
- [x] Add CSS for volume meter bar
|
||||
- [x] Add gradient colors (green → yellow → red)
|
||||
- [x] Add percentage text display
|
||||
- [x] Add "No input detected" indicator
|
||||
- **Validation**: Visual feedback is clear and responsive
|
||||
|
||||
## Phase 3: Test Recording
|
||||
|
||||
### Task 3.1: Implement Test Recording Function
|
||||
- [x] Create `startTestRecording()` function
|
||||
- [x] Use MediaRecorder with selected device
|
||||
- [x] Implement 5-second auto-stop timer
|
||||
- [x] Store recording as Blob
|
||||
- [x] Update UI during recording (countdown, indicator)
|
||||
- **Validation**: Can record 5 seconds, blob created
|
||||
|
||||
### Task 3.2: Implement Test Playback Function
|
||||
- [x] Create `playTestRecording()` function
|
||||
- [x] Create Audio element from blob URL
|
||||
- [x] Handle play/stop states
|
||||
- [x] Update UI during playback
|
||||
- [x] Clean up blob URL when done
|
||||
- **Validation**: Recorded audio plays back correctly
|
||||
|
||||
### Task 3.3: Test Recording UI State Management
|
||||
- [x] Disable recording button during recording
|
||||
- [x] Show countdown timer during recording
|
||||
- [x] Enable play button after recording
|
||||
- [x] Disable test controls during main recording
|
||||
- **Validation**: UI states transition correctly
|
||||
|
||||
## Phase 4: Integration
|
||||
|
||||
### Task 4.1: Integrate with Main Recording
|
||||
- [x] Modify `startRecording()` to use selected device
|
||||
- [x] Add fallback to auto-selection if no preference
|
||||
- [x] Handle selected device being unavailable
|
||||
- [x] Stop volume monitoring during main recording
|
||||
- **Validation**: Main recording uses selected device
|
||||
|
||||
### Task 4.2: Add Panel Collapse/Expand
|
||||
- [x] Add collapse toggle button
|
||||
- [x] Save panel state to localStorage
|
||||
- [x] Load panel state on page load
|
||||
- [x] Stop volume monitoring when collapsed
|
||||
- **Validation**: Panel remembers collapse state
|
||||
|
||||
### Task 4.3: Add Refresh Device List Button
|
||||
- [x] Add refresh icon button
|
||||
- [x] Re-enumerate devices on click
|
||||
- [x] Preserve selection if still available
|
||||
- [x] Update dropdown options
|
||||
- **Validation**: New devices appear after refresh
|
||||
|
||||
## Phase 5: Polish & Error Handling
|
||||
|
||||
### Task 5.1: Error Handling
|
||||
- [x] Handle "No devices found" state
|
||||
- [x] Handle permission denied errors
|
||||
- [x] Handle device disconnection during use
|
||||
- [x] Show user-friendly error messages (Chinese)
|
||||
- **Validation**: All error states show appropriate messages
|
||||
|
||||
### Task 5.2: Localization
|
||||
- [x] Add Chinese labels for all UI elements
|
||||
- [x] Add Chinese error messages
|
||||
- [x] Add tooltips for buttons
|
||||
- **Validation**: All text is in Traditional Chinese
|
||||
|
||||
### Task 5.3: Testing & Documentation
|
||||
- [x] Manual testing with multiple microphones
|
||||
- [x] Test USB microphone hot-plug
|
||||
- [x] Test headset microphone switching
|
||||
- [x] Update DEPLOYMENT.md if needed
|
||||
- **Validation**: Feature works with various microphone types
|
||||
|
||||
## Dependencies
|
||||
- Task 1.2 depends on Task 1.1
|
||||
- Task 2.1 depends on Task 1.3
|
||||
- Task 3.1 depends on Task 1.3
|
||||
- Task 4.1 depends on Tasks 1.3, 3.1
|
||||
- Phase 5 depends on all previous phases
|
||||
|
||||
## Parallelizable Work
|
||||
- Task 1.1 (HTML) and Task 2.2 (CSS) can run in parallel
|
||||
- Task 3.1 (Recording) and Task 2.1 (Volume) can run in parallel after Task 1.3
|
||||
Reference in New Issue
Block a user