fix(voice): robust microphone fallback for WebKitGTK "Invalid constraint"
All checks were successful
Build AppImage / build (push) Has been skipped
All checks were successful
Build AppImage / build (push) Has been skipped
WebKitGTK throws various error types (TypeError, OverconstrainedError,
etc.) when getUserMedia is called. Instead of only catching specific
error names, now ALL errors trigger device-enumeration fallback chain:
1. { audio: true }
2. Explicit deviceId from enumerateDevices()
3. { audio: {} } as last resort
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
5d72b85bf4
commit
e0653ddcab
2 changed files with 30 additions and 15 deletions
|
|
@ -261,28 +261,29 @@
|
|||
try {
|
||||
stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
||||
} catch (initialErr) {
|
||||
// OverconstrainedError oder NotFoundError — auf WebKitGTK/Tauri kann
|
||||
// selbst { audio: true } fehlschlagen. Versuche explizites Device.
|
||||
if (initialErr instanceof DOMException &&
|
||||
(initialErr.name === 'OverconstrainedError' || initialErr.name === 'NotFoundError')) {
|
||||
console.warn('getUserMedia fehlgeschlagen, versuche Device-Enumeration:', initialErr);
|
||||
// WebKitGTK wirft verschiedene Fehler: OverconstrainedError, NotFoundError,
|
||||
// TypeError("Invalid constraint"), etc. Bei JEDEM Fehler Fallback versuchen.
|
||||
console.warn('getUserMedia({audio:true}) fehlgeschlagen, versuche Fallback:', initialErr);
|
||||
|
||||
try {
|
||||
const devices = await navigator.mediaDevices.enumerateDevices();
|
||||
const audioInput = devices.find(d => d.kind === 'audioinput');
|
||||
|
||||
if (audioInput) {
|
||||
console.log('Audio-Device gefunden:', audioInput.label || audioInput.deviceId);
|
||||
stream = await navigator.mediaDevices.getUserMedia({
|
||||
audio: { deviceId: audioInput.deviceId }
|
||||
audio: { deviceId: { exact: audioInput.deviceId } }
|
||||
});
|
||||
} else {
|
||||
throw new Error(
|
||||
'Kein Mikrofon gefunden. Unter WebKitGTK (Tauri/Linux) wird ' +
|
||||
'PipeWire oder PulseAudio mit gst-plugin-pipewire benötigt.'
|
||||
);
|
||||
// Letzter Versuch: komplett ohne Constraints
|
||||
stream = await navigator.mediaDevices.getUserMedia({ audio: {} });
|
||||
}
|
||||
} else {
|
||||
throw initialErr;
|
||||
} catch (fallbackErr) {
|
||||
throw new Error(
|
||||
'Kein Mikrofon verfügbar. Unter WebKitGTK (Tauri/Linux) wird ' +
|
||||
'PipeWire oder PulseAudio mit gst-plugin-pipewire benötigt. ' +
|
||||
`Original: ${initialErr instanceof Error ? initialErr.message : initialErr}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -77,10 +77,24 @@
|
|||
});
|
||||
console.log('🎤 Mikrofon mit optimalen Constraints geöffnet');
|
||||
} catch (constraintErr) {
|
||||
console.warn('Mikrofon-Constraints fehlgeschlagen, versuche Fallback:', constraintErr);
|
||||
mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
||||
// WebKitGTK wirft diverse Fehler (OverconstrainedError, TypeError "Invalid constraint", etc.)
|
||||
console.warn('Mikrofon-Constraints fehlgeschlagen, versuche Fallbacks:', constraintErr);
|
||||
try {
|
||||
mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
||||
} catch (_) {
|
||||
// Auch { audio: true } fehlgeschlagen — versuche explizites Device
|
||||
const devices = await navigator.mediaDevices.enumerateDevices();
|
||||
const audioInput = devices.find(d => d.kind === 'audioinput');
|
||||
if (audioInput) {
|
||||
mediaStream = await navigator.mediaDevices.getUserMedia({
|
||||
audio: { deviceId: { exact: audioInput.deviceId } }
|
||||
});
|
||||
} else {
|
||||
mediaStream = await navigator.mediaDevices.getUserMedia({ audio: {} });
|
||||
}
|
||||
}
|
||||
usedFallback = true;
|
||||
console.log('🎤 Mikrofon mit Fallback { audio: true } geöffnet');
|
||||
console.log('🎤 Mikrofon mit Fallback geöffnet');
|
||||
}
|
||||
|
||||
// Audio-Kontext für Visualisierung
|
||||
|
|
|
|||
Loading…
Reference in a new issue