From cd239fde3c2a3951bfaae98dfd769069a3c207aa Mon Sep 17 00:00:00 2001 From: "info@pi-farm.de" Date: Thu, 28 May 2026 00:02:08 +0000 Subject: [PATCH] jarvis.py aktualisiert --- jarvis.py | 59 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/jarvis.py b/jarvis.py index 7e271ef..e09582c 100644 --- a/jarvis.py +++ b/jarvis.py @@ -5,6 +5,7 @@ import asyncio import openai import sys import subprocess +import edge_tts from google import genai from google.genai import types @@ -544,28 +545,44 @@ async def speak_to_user(text): print(text) print(f"{JARVIS_COLOR}{'-'*60}{RESET}\n") - clean_text = re.sub(r'[^\w\s\d.,!?-]', '', text) - - piper_path = "/home/meik/jarvis-ai/piper/piper" - model_path = "/home/meik/jarvis-ai/de_DE-thorsten-high.onnx" - lock_file = Path("/tmp/.jarvis_speaking") # Die Sperr-Datei + """Generiert eine hochauflösende KI-Stimme via Edge-TTS und spielt sie ab.""" + if not text.strip(): + return - if os.path.exists(piper_path) and os.path.exists(model_path): - try: - # 1. Sperre setzen - lock_file.touch() - - piper_cmd = f"echo '{clean_text}' | {piper_path} --model {model_path} --output_raw | aplay -r 22050 -f S16_LE -t raw -D pipewire >/dev/null 2>&1" - - proc = await asyncio.create_subprocess_shell(piper_cmd) - await proc.wait() - - except Exception as e: - print(f"⚠️ TTS Fehler: {e}") - finally: - # 2. Sperre IMMER wieder aufheben, wenn Piper fertig ist - if lock_file.exists(): - lock_file.unlink() + # Definition der Stimme (Killian und Conrad sind hervorragende deutsche Männerstimmen) + VOICE = "de-DE-KillianNeural" + OUTPUT_FILE = "/tmp/jarvis_response.mp3" + LOCK_FILE = "/tmp/.jarvis_speaking" + + # Innerer asynchroner Task für den Cloud-Abruf + async def generate_audio(): + communicate = edge_tts.Communicate(text, VOICE) + await communicate.save(OUTPUT_FILE) + + try: + # 1. Erstelle die Lock-Datei, damit das Mikrofon im Wakeword-Skript stummschaltet + with open(LOCK_FILE, "w") as f: + f.write("1") + + print(f"🔊 J.A.R.V.I.S. spricht: {text}") + + # 2. Audio aus der Cloud abrufen + asyncio.run(generate_audio()) + + # 3. Audio ressourcenschonend abspielen (stdout/err unterdrücken) + subprocess.run( + ["mpv", "--no-video", OUTPUT_FILE], + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL + ) + + except Exception as e: + print(f"❌ Fehler bei der Sprachausgabe: {e}") + + finally: + # 4. Lock-Datei IMMER löschen, damit J.A.R.V.I.S. wieder zuhört + if os.path.exists(LOCK_FILE): + os.remove(LOCK_FILE) # ==================================================== # MAIN LOOP