From 568ef9ed1077ad521d11aef3c1eeffef236fd706 Mon Sep 17 00:00:00 2001 From: duffyduck Date: Wed, 6 May 2026 22:59:20 +0200 Subject: [PATCH] fix(audio): STT-Cleanup-Timeout skaliert mit Aufnahmedauer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Der pauschale 30s-Timeout vom Vorgaenger-Commit haette bei einer 5-Minuten-Aufnahme schon getriggert waehrend Whisper noch transkribiert (Whisper braucht auf der Gamebox-GPU grob real-time/5, plus Bridge- Roundtrip). Neue Formel: 60s Buffer + 1x Aufnahmedauer. - 5s Aufnahme → 65s Wait - 5min Aufnahme → 6 min Wait - 30min Aufnahme → 31 min Wait Co-Authored-By: Claude Opus 4.7 (1M context) --- android/src/screens/ChatScreen.tsx | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/android/src/screens/ChatScreen.tsx b/android/src/screens/ChatScreen.tsx index f6c9200..1b66e90 100644 --- a/android/src/screens/ChatScreen.tsx +++ b/android/src/screens/ChatScreen.tsx @@ -535,7 +535,7 @@ const ChatScreen: React.FC = () => { audioRequestId, ...(location && { location }), }); - scheduleStaleAudioCleanup(audioRequestId); + scheduleStaleAudioCleanup(audioRequestId, result.durationMs); // resume() wird durch onPlaybackFinished nach ARIAs Antwort getriggert. } else { // Kein Speech im Window → Konversation beenden (Ohr geht aus oder @@ -658,10 +658,13 @@ const ChatScreen: React.FC = () => { // --- Nachricht senden --- // Aufraeumen von "verarbeitet"-Placeholder die nie ein STT-Result bekommen - // haben (leere Aufnahme, Wake-Word-Echo, STT-Fehler etc). Nach 30s werden - // sie automatisch entfernt damit nicht-erkannte Aufnahmen nicht den State - // verstopfen + naechste echte Aufnahmen die richtige Bubble ersetzen koennen. - const scheduleStaleAudioCleanup = useCallback((audioRequestId: string) => { + // haben (leere Aufnahme, Wake-Word-Echo, STT-Fehler etc). Timeout skaliert + // mit der Aufnahmedauer — Whisper braucht auf der Gamebox grob real-time/5, + // plus Bridge-Roundtrip + Network. Formel: 60s Buffer + 1x Aufnahmedauer. + // Bei 5min Aufnahme = 6 min Wait, bei 5s Aufnahme = 65s. Sicher genug damit + // langsame STTs nicht versehentlich aufgeraeumt werden. + const scheduleStaleAudioCleanup = useCallback((audioRequestId: string, recordingMs: number) => { + const timeoutMs = 60000 + recordingMs; setTimeout(() => { setMessages(prev => { const idx = prev.findIndex(m => @@ -669,11 +672,12 @@ const ChatScreen: React.FC = () => { m.text.includes('Spracheingabe wird verarbeitet') ); if (idx < 0) return prev; - console.log('[Chat] Sprachnachricht ohne STT-Result entfernt: %s', audioRequestId); + console.log('[Chat] Sprachnachricht ohne STT-Result nach %dms entfernt: %s', + timeoutMs, audioRequestId); ToastAndroid.show('Sprachnachricht nicht erkannt — entfernt', ToastAndroid.SHORT); return prev.filter((_, i) => i !== idx); }); - }, 30000); + }, timeoutMs); }, []); const sendTextMessage = useCallback(async () => { @@ -763,7 +767,7 @@ const ChatScreen: React.FC = () => { audioRequestId, ...(location && { location }), }); - scheduleStaleAudioCleanup(audioRequestId); + scheduleStaleAudioCleanup(audioRequestId, result.durationMs); }, [getCurrentLocation, interruptAriaIfBusy, scheduleStaleAudioCleanup]); // Datei auswaehlen → zur Pending-Liste hinzufuegen