Feat: Hermes Voice Client (Wake Word + STT + Vision + TTS)
Windows-Desktop-Script: Energy VAD + Whisper Wake Detection, faster-whisper STT, mss Screen Capture, MC2 Vision/Chat API, Edge TTS Ausgabe, pystray System Tray. Kein Account nötig — Wake Word frei konfigurierbar via WAKE_WORDS in config.py. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
import asyncio
|
||||
import os
|
||||
import tempfile
|
||||
import threading
|
||||
import pygame
|
||||
import edge_tts
|
||||
from config import TTS_VOICE, TTS_RATE, TTS_PITCH
|
||||
|
||||
pygame.mixer.init()
|
||||
_stop_event = threading.Event()
|
||||
|
||||
|
||||
def stop_speaking():
|
||||
"""Unterbricht laufende Sprachausgabe (z.B. wenn User spricht)."""
|
||||
_stop_event.set()
|
||||
pygame.mixer.music.stop()
|
||||
|
||||
|
||||
def speak(text: str):
|
||||
"""Text → Edge TTS → Lautsprecher. Blockiert bis fertig oder unterbrochen."""
|
||||
_stop_event.clear()
|
||||
|
||||
async def _run():
|
||||
with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as f:
|
||||
tmp_path = f.name
|
||||
|
||||
communicate = edge_tts.Communicate(text, TTS_VOICE, rate=TTS_RATE, pitch=TTS_PITCH)
|
||||
await communicate.save(tmp_path)
|
||||
|
||||
if _stop_event.is_set():
|
||||
os.unlink(tmp_path)
|
||||
return
|
||||
|
||||
pygame.mixer.music.load(tmp_path)
|
||||
pygame.mixer.music.play()
|
||||
|
||||
while pygame.mixer.music.get_busy():
|
||||
if _stop_event.is_set():
|
||||
pygame.mixer.music.stop()
|
||||
break
|
||||
pygame.time.wait(50)
|
||||
|
||||
os.unlink(tmp_path)
|
||||
|
||||
asyncio.run(_run())
|
||||
|
||||
|
||||
def play_ding():
|
||||
"""Kurzer Aktivierungs-Ton (440 Hz, 120ms)."""
|
||||
import numpy as np
|
||||
sample_rate = 44100
|
||||
duration = 0.12
|
||||
t = np.linspace(0, duration, int(sample_rate * duration), False)
|
||||
wave = (np.sin(2 * np.pi * 440 * t) * 0.3 * 32767).astype(np.int16)
|
||||
stereo = np.column_stack([wave, wave])
|
||||
sound = pygame.sndarray.make_sound(stereo)
|
||||
sound.play()
|
||||
pygame.time.wait(int(duration * 1000) + 20)
|
||||
Reference in New Issue
Block a user