fix: Improve microphone permission handling and audio capture robustness
- Add device enumeration check before attempting to capture audio - Use simpler audio constraints (audio: true) instead of specific options - Add fallback to explicit device ID if simple constraints fail - Add more descriptive error messages for different failure modes - Enhance Electron permission handlers with better logging - Add setDevicePermissionHandler for audio device access - Include 'microphone' in allowed permissions list 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -446,8 +446,10 @@ app.whenReady().then(async () => {
|
||||
loadConfig();
|
||||
|
||||
// Grant microphone permission automatically
|
||||
session.defaultSession.setPermissionRequestHandler((webContents, permission, callback) => {
|
||||
const allowedPermissions = ['media', 'mediaKeySystem', 'audioCapture'];
|
||||
session.defaultSession.setPermissionRequestHandler((webContents, permission, callback, details) => {
|
||||
console.log(`Permission request: ${permission}`, details);
|
||||
// Allow all media-related permissions
|
||||
const allowedPermissions = ['media', 'mediaKeySystem', 'audioCapture', 'microphone'];
|
||||
if (allowedPermissions.includes(permission)) {
|
||||
console.log(`Granting permission: ${permission}`);
|
||||
callback(true);
|
||||
@@ -458,11 +460,22 @@ app.whenReady().then(async () => {
|
||||
});
|
||||
|
||||
// Also handle permission check (for some Electron versions)
|
||||
session.defaultSession.setPermissionCheckHandler((webContents, permission) => {
|
||||
const allowedPermissions = ['media', 'mediaKeySystem', 'audioCapture'];
|
||||
session.defaultSession.setPermissionCheckHandler((webContents, permission, requestingOrigin, details) => {
|
||||
console.log(`Permission check: ${permission}`, { requestingOrigin, details });
|
||||
const allowedPermissions = ['media', 'mediaKeySystem', 'audioCapture', 'microphone'];
|
||||
return allowedPermissions.includes(permission);
|
||||
});
|
||||
|
||||
// Set device permission handler for media devices
|
||||
session.defaultSession.setDevicePermissionHandler((details) => {
|
||||
console.log('Device permission request:', details);
|
||||
// Allow all audio devices
|
||||
if (details.deviceType === 'audio' || details.deviceType === 'hid') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
// Start backend sidecar if embedded mode is enabled
|
||||
startBackendSidecar();
|
||||
|
||||
|
||||
@@ -405,9 +405,26 @@
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for available audio devices first
|
||||
const devices = await navigator.mediaDevices.enumerateDevices();
|
||||
const audioInputs = devices.filter(d => d.kind === 'audioinput');
|
||||
console.log('Available audio inputs:', audioInputs.length, audioInputs);
|
||||
|
||||
if (audioInputs.length === 0) {
|
||||
alert('No microphone found. Please connect a microphone and try again.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Try with simple constraints first, fall back to more specific ones
|
||||
try {
|
||||
mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
||||
} catch (simpleErr) {
|
||||
console.warn('Simple audio constraints failed, trying with device ID:', simpleErr);
|
||||
// Try with explicit device ID
|
||||
mediaStream = await navigator.mediaDevices.getUserMedia({
|
||||
audio: { echoCancellation: true, noiseSuppression: true }
|
||||
audio: { deviceId: audioInputs[0].deviceId }
|
||||
});
|
||||
}
|
||||
|
||||
isRecording = true;
|
||||
recordBtn.textContent = 'Stop Recording';
|
||||
@@ -422,7 +439,15 @@
|
||||
|
||||
} catch (error) {
|
||||
console.error('Start recording error:', error);
|
||||
alert('Error starting recording: ' + error.message);
|
||||
let errorMsg = 'Error starting recording: ' + error.message;
|
||||
if (error.name === 'NotAllowedError') {
|
||||
errorMsg = 'Microphone access denied. Please grant permission and try again.';
|
||||
} else if (error.name === 'NotFoundError') {
|
||||
errorMsg = 'No microphone found. Please connect a microphone and try again.';
|
||||
} else if (error.name === 'NotReadableError') {
|
||||
errorMsg = 'Microphone is in use by another application. Please close other apps using the microphone.';
|
||||
}
|
||||
alert(errorMsg);
|
||||
await cleanupRecording();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user