Feat: Sprechen-Tab — mit Hermes per Sprache reden (Browser-Voice + 3D-Avatar)
Voll-Duplex Sprach-Interaktion vom lokalen PC mit dem vollen Hermes-Agenten (api_server :8642, OpenAI-kompatibel → gleiche Tools + geteiltes Mem0 wie CLI/Telegram). - Voice-Sidecar (voice_service/, eigenes Py3.12-venv ~/.voice, :8650): STT faster-whisper (medium, de) + gestuftes TTS — Piper (schnell, Default) + Chatterbox (premium, Voice-Cloning, lazy-load, CPU-Start). Analog mem0_service. - Backend: routers/voice.py (Proxy /api/voice/stt|tts|voices + /chat-SSE an Hermes mit Bearer API_SERVER_KEY + X-Hermes-Session-Id für server-seitigen Verlauf). config.py: VOICE_SERVICE_URL + HERMES_API_KEY (Fallback aus ~/.hermes/.env). System-Dienstliste + Wartung (Restart/Logs) um voice-service ergänzt. - Frontend: Sprechen-Tab mit 3D-Avatar (VRM via three-vrm) — Lippensync (Web-Audio-Pegel), Blinzeln, Sentiment-Mimik, Ruhepose. Avatar-Picker (CORS-freie Galerie + .vrm-Upload + URL + VRoid-Hub-Link) + Stimm-Auswahl. Push-to-talk (Knopf/Leertaste). Deps: three, r3f, drei. - Deploy: deploy/voice-service.service + deploy.sh (idempotenter Sidecar-Install, enable, restart). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env bash
|
||||
# Voice-Sidecar-Setup AUF DER BOX (User hitonabi, sudo-frei). Idempotent — Erstinstallation
|
||||
# + Updates. Eigenes Python-3.12-venv (~/.voice/venv), weil torch/chatterbox/faster-whisper
|
||||
# nicht ins 3.14-Backend-venv passen (analog ~/.mem0/venv). Wird von deploy/deploy.sh aufgerufen.
|
||||
set -euo pipefail
|
||||
|
||||
SRC="${MC2_SRC:-$HOME/mission-control-v2}"
|
||||
VENV="$HOME/.voice/venv"
|
||||
VOICES="$HOME/.voice/voices"
|
||||
PY="${VOICE_PYTHON:-python3.12}"
|
||||
|
||||
command -v "$PY" >/dev/null 2>&1 || PY=python3 # Fallback, falls python3.12 nicht im PATH
|
||||
|
||||
# --- venv -------------------------------------------------------------------
|
||||
if [ ! -x "$VENV/bin/python" ]; then
|
||||
echo "[voice] Erstelle venv ($PY) → $VENV"
|
||||
"$PY" -m venv "$VENV"
|
||||
fi
|
||||
"$VENV/bin/python" -m pip install -q --upgrade pip
|
||||
|
||||
# --- Kern-Deps (STT + Piper + Server) — required ----------------------------
|
||||
echo "[voice] Installiere Kern-Abhängigkeiten …"
|
||||
"$VENV/bin/python" -m pip install -q -r "$SRC/voice_service/requirements.txt"
|
||||
|
||||
# --- Chatterbox (Premium-TTS) — best-effort, CPU-torch (kein 2-GB-CUDA-Wheel) ----
|
||||
echo "[voice] Installiere Chatterbox (Premium-TTS, CPU-torch) — best-effort …"
|
||||
if "$VENV/bin/python" -m pip install -q --index-url https://download.pytorch.org/whl/cpu torch torchaudio \
|
||||
&& "$VENV/bin/python" -m pip install -q chatterbox-tts; then
|
||||
echo "[voice] Chatterbox bereit."
|
||||
else
|
||||
echo "[voice] WARN: Chatterbox-Install fehlgeschlagen — Piper bleibt als Default-Stimme aktiv."
|
||||
fi
|
||||
|
||||
# --- Piper-Stimmen (Deutsch) nach ~/.voice/voices ---------------------------
|
||||
mkdir -p "$VOICES"
|
||||
BASE="https://huggingface.co/rhasspy/piper-voices/resolve/main/de/de_DE"
|
||||
get_voice() { # $1=relpfad-ohne-endung $2=dateibasis
|
||||
local rel="$1" name="$2"
|
||||
for ext in onnx onnx.json; do
|
||||
if [ ! -f "$VOICES/$name.$ext" ]; then
|
||||
echo "[voice] Lade Piper-Stimme $name.$ext …"
|
||||
curl -fsSL "$BASE/$rel/$name.$ext" -o "$VOICES/$name.$ext" \
|
||||
|| echo "[voice] WARN: $name.$ext konnte nicht geladen werden."
|
||||
fi
|
||||
done
|
||||
}
|
||||
get_voice "thorsten/medium" "de_DE-thorsten-medium" # Default (schnell, klar)
|
||||
get_voice "thorsten/high" "de_DE-thorsten-high" # natürlicher, etwas langsamer
|
||||
get_voice "kerstin/low" "de_DE-kerstin-low" # weibliche Alternative
|
||||
|
||||
echo "[voice] Fertig. Stimmen in $VOICES:"
|
||||
ls -1 "$VOICES"/*.onnx 2>/dev/null || echo "[voice] WARN: keine Piper-Stimme vorhanden!"
|
||||
Reference in New Issue
Block a user