diff --git a/src/lib/components/ChatPanel.svelte b/src/lib/components/ChatPanel.svelte index 485d9f5..f2ead0a 100644 --- a/src/lib/components/ChatPanel.svelte +++ b/src/lib/components/ChatPanel.svelte @@ -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}` + ); } } diff --git a/src/lib/components/VoicePanel.svelte b/src/lib/components/VoicePanel.svelte index 8f9c37d..4516ec1 100644 --- a/src/lib/components/VoicePanel.svelte +++ b/src/lib/components/VoicePanel.svelte @@ -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