wait for finish tts
This commit is contained in:
parent
892639d626
commit
b830388d9f
|
|
@ -136,6 +136,12 @@ class ClaudesEyesAudioBridge:
|
||||||
self._speaking = threading.Event()
|
self._speaking = threading.Event()
|
||||||
self._speaking.clear() # Anfangs nicht am Sprechen
|
self._speaking.clear() # Anfangs nicht am Sprechen
|
||||||
|
|
||||||
|
# Awaiting-TTS-Flag: Wird gesetzt wenn Nachricht gesendet wurde
|
||||||
|
# und wir auf TTS warten. Erst clearen wenn TTS komplett fertig ist.
|
||||||
|
# So wartet Heartbeat auch während gTTS das Audio generiert.
|
||||||
|
self._awaiting_tts = threading.Event()
|
||||||
|
self._awaiting_tts.clear() # Anfangs nicht wartend
|
||||||
|
|
||||||
# Mute-Flag: Wenn True, ignoriert STT alle Eingaben
|
# Mute-Flag: Wenn True, ignoriert STT alle Eingaben
|
||||||
# Startet gemutet um ungewollte Aufnahmen zu vermeiden
|
# Startet gemutet um ungewollte Aufnahmen zu vermeiden
|
||||||
self._muted = True
|
self._muted = True
|
||||||
|
|
@ -642,19 +648,21 @@ Erst dann starten die automatischen TICKs mit Bildern!"""
|
||||||
break
|
break
|
||||||
|
|
||||||
# ════════════════════════════════════════════════════════════════
|
# ════════════════════════════════════════════════════════════════
|
||||||
# WICHTIG: Nach dem Claude fertig getippt hat, warte kurz damit
|
# WICHTIG: Warte bis TTS komplett fertig ist!
|
||||||
# TTS die Nachricht finden und mit Sprechen beginnen kann.
|
# _awaiting_tts wurde beim Senden gesetzt und wird erst
|
||||||
# Dann warte bis TTS fertig ist.
|
# gelöscht wenn TTS die Nachricht vorgelesen hat (oder wenn
|
||||||
|
# es nichts vorzulesen gab).
|
||||||
# ════════════════════════════════════════════════════════════════
|
# ════════════════════════════════════════════════════════════════
|
||||||
logger.debug("Claude fertig mit Tippen, warte auf TTS...")
|
if self._awaiting_tts.is_set():
|
||||||
time.sleep(1.5) # Kurz warten bis TTS die Nachricht findet
|
logger.info("Heartbeat: Warte auf TTS (Nachricht wurde gesendet)...")
|
||||||
|
|
||||||
# Jetzt warte bis TTS fertig ist mit Sprechen
|
# Warte bis TTS komplett fertig ist (kein Timeout!)
|
||||||
if self._speaking.is_set():
|
while self.running and self._awaiting_tts.is_set():
|
||||||
logger.debug("Claude spricht (TTS), warte bis fertig...")
|
if self._speaking.is_set():
|
||||||
while self.running and self._speaking.is_set():
|
logger.debug("Heartbeat: Claude spricht gerade...")
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
logger.debug("Claude fertig mit Sprechen")
|
|
||||||
|
logger.info("Heartbeat: TTS fertig, fahre fort")
|
||||||
|
|
||||||
if not self.running:
|
if not self.running:
|
||||||
break
|
break
|
||||||
|
|
@ -708,6 +716,10 @@ Erst dann starten die automatischen TICKs mit Bildern!"""
|
||||||
stefan_message = f"Stefan sagt: {stefan_text}"
|
stefan_message = f"Stefan sagt: {stefan_text}"
|
||||||
console.print(f"[green]🎤 Stefan:[/green] {stefan_text[:100]}{'...' if len(stefan_text) > 100 else ''}")
|
console.print(f"[green]🎤 Stefan:[/green] {stefan_text[:100]}{'...' if len(stefan_text) > 100 else ''}")
|
||||||
|
|
||||||
|
# WICHTIG: Signalisiere dass wir auf TTS warten
|
||||||
|
self._awaiting_tts.set()
|
||||||
|
logger.debug("_awaiting_tts gesetzt (Stefan-Nachricht)")
|
||||||
|
|
||||||
self.chat.send_message(stefan_message)
|
self.chat.send_message(stefan_message)
|
||||||
self.stats.ticks_sent += 1
|
self.stats.ticks_sent += 1
|
||||||
self.consecutive_errors = 0
|
self.consecutive_errors = 0
|
||||||
|
|
@ -745,6 +757,10 @@ Erst dann starten die automatischen TICKs mit Bildern!"""
|
||||||
tick_message = "[TICK]"
|
tick_message = "[TICK]"
|
||||||
console.print("[dim]→ TICK[/dim]")
|
console.print("[dim]→ TICK[/dim]")
|
||||||
|
|
||||||
|
# WICHTIG: Signalisiere dass wir auf TTS warten
|
||||||
|
self._awaiting_tts.set()
|
||||||
|
logger.debug("_awaiting_tts gesetzt (TICK)")
|
||||||
|
|
||||||
success = self.chat.send_message(tick_message)
|
success = self.chat.send_message(tick_message)
|
||||||
|
|
||||||
if success:
|
if success:
|
||||||
|
|
@ -840,15 +856,7 @@ Erst dann starten die automatischen TICKs mit Bildern!"""
|
||||||
if self._current_chat_id:
|
if self._current_chat_id:
|
||||||
self._save_tts_state(self._current_chat_id, msg.id)
|
self._save_tts_state(self._current_chat_id, msg.id)
|
||||||
|
|
||||||
# ════════════════════════════════════════════════════════════════
|
# Text für Sprache aufbereiten (Steuercodes etc. entfernen)
|
||||||
# WICHTIG: Nachrichten mit Steuercodes werden NICHT vorgelesen!
|
|
||||||
# Diese sind reine Roboter-Befehle, keine Sprache für Stefan.
|
|
||||||
# ════════════════════════════════════════════════════════════════
|
|
||||||
if self._contains_control_codes(msg.text):
|
|
||||||
logger.debug(f"TTS: Nachricht enthält Steuercodes, übersprungen")
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Text für Sprache aufbereiten
|
|
||||||
speech_text = self._clean_for_speech(msg.text)
|
speech_text = self._clean_for_speech(msg.text)
|
||||||
logger.debug(f"TTS: Original: '{msg.text[:100]}...'")
|
logger.debug(f"TTS: Original: '{msg.text[:100]}...'")
|
||||||
logger.debug(f"TTS: Nach Bereinigung: '{speech_text[:100] if speech_text else ''}' ({len(speech_text) if speech_text else 0} Zeichen)")
|
logger.debug(f"TTS: Nach Bereinigung: '{speech_text[:100] if speech_text else ''}' ({len(speech_text) if speech_text else 0} Zeichen)")
|
||||||
|
|
@ -859,10 +867,13 @@ Erst dann starten die automatischen TICKs mit Bildern!"""
|
||||||
tts_text = tts_text[12:].strip()
|
tts_text = tts_text[12:].strip()
|
||||||
logger.debug(f"TTS: 'Claude sagt:' entfernt, Rest: '{tts_text}' ({len(tts_text)} Zeichen)")
|
logger.debug(f"TTS: 'Claude sagt:' entfernt, Rest: '{tts_text}' ({len(tts_text)} Zeichen)")
|
||||||
|
|
||||||
# Prüfe ob nach Entfernen noch Text übrig ist
|
# Prüfe ob nach Entfernen noch sprechbarer Text übrig ist
|
||||||
# Kein Mindestlänge-Check damit auch kurze Antworten wie "Ja!" gesprochen werden
|
# Kein Mindestlänge-Check damit auch kurze Antworten wie "Ja!" gesprochen werden
|
||||||
if not tts_text:
|
if not tts_text or not tts_text.strip():
|
||||||
logger.info(f"TTS: Nach Prefix-Entfernung kein Text übrig, übersprungen (Original: '{msg.text[:50]}')")
|
logger.info(f"TTS: Nach Bereinigung kein sprechbarer Text übrig, übersprungen (Original: '{msg.text[:80]}')")
|
||||||
|
# Trotzdem _awaiting_tts clearen - die Nachricht wurde verarbeitet!
|
||||||
|
self._awaiting_tts.clear()
|
||||||
|
logger.debug("TTS: _awaiting_tts.clear() (kein sprechbarer Text)")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# In Konsole anzeigen (ohne Prefix)
|
# In Konsole anzeigen (ohne Prefix)
|
||||||
|
|
@ -872,14 +883,15 @@ Erst dann starten die automatischen TICKs mit Bildern!"""
|
||||||
|
|
||||||
# Vorlesen (ohne "Claude sagt:" - das ist ja klar)
|
# Vorlesen (ohne "Claude sagt:" - das ist ja klar)
|
||||||
# WICHTIG: Speaking-Flag setzen damit Heartbeat wartet!
|
# WICHTIG: Speaking-Flag setzen damit Heartbeat wartet!
|
||||||
logger.info(f"TTS: Spreche {len(tts_text)} Zeichen...")
|
logger.info(f"TTS: _speaking.set() - Spreche {len(tts_text)} Zeichen: '{tts_text[:50]}...'")
|
||||||
self._speaking.set() # Signalisiere: Claude spricht!
|
self._speaking.set() # Signalisiere: Claude spricht!
|
||||||
try:
|
try:
|
||||||
self.tts.speak(tts_text)
|
self.tts.speak(tts_text)
|
||||||
finally:
|
finally:
|
||||||
self._speaking.clear() # Fertig mit Sprechen
|
self._speaking.clear() # Fertig mit Sprechen
|
||||||
|
self._awaiting_tts.clear() # TTS komplett fertig!
|
||||||
|
logger.info("TTS: _speaking.clear() + _awaiting_tts.clear() - Fertig mit Sprechen")
|
||||||
self.stats.messages_spoken += 1
|
self.stats.messages_spoken += 1
|
||||||
logger.debug("TTS: Sprechen beendet")
|
|
||||||
else:
|
else:
|
||||||
logger.debug(f"TTS: Nachricht ist nicht von Claude, übersprungen")
|
logger.debug(f"TTS: Nachricht ist nicht von Claude, übersprungen")
|
||||||
|
|
||||||
|
|
@ -922,10 +934,10 @@ Erst dann starten die automatischen TICKs mit Bildern!"""
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# WICHTIG: Wenn Claude spricht (TTS), nicht aufzeichnen!
|
# WICHTIG: Wenn Claude spricht (TTS) oder wir auf TTS warten, nicht aufzeichnen!
|
||||||
# Das verhindert Echo (Mikrofon nimmt TTS auf) und
|
# Das verhindert Echo (Mikrofon nimmt TTS auf) und
|
||||||
# überlappende Gespräche - wir lassen Claude ausreden.
|
# überlappende Gespräche - wir lassen Claude ausreden.
|
||||||
if self._speaking.is_set():
|
if self._speaking.is_set() or self._awaiting_tts.is_set():
|
||||||
# Falls wir mitten in einer Aufnahme waren, diese beenden
|
# Falls wir mitten in einer Aufnahme waren, diese beenden
|
||||||
if self._recording.is_set():
|
if self._recording.is_set():
|
||||||
self._finalize_recording(current_session_texts)
|
self._finalize_recording(current_session_texts)
|
||||||
|
|
@ -937,7 +949,7 @@ Erst dann starten die automatischen TICKs mit Bildern!"""
|
||||||
result = self.stt.listen_once(timeout=1)
|
result = self.stt.listen_once(timeout=1)
|
||||||
|
|
||||||
# Nochmal prüfen nach dem Hören (falls zwischendurch gemutet oder Claude spricht)
|
# Nochmal prüfen nach dem Hören (falls zwischendurch gemutet oder Claude spricht)
|
||||||
if self.is_muted() or self._speaking.is_set():
|
if self.is_muted() or self._speaking.is_set() or self._awaiting_tts.is_set():
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if result and result.text and len(result.text) > 2:
|
if result and result.text and len(result.text) > 2:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue