Ein lokaler Text-to-Speech-Assistent auf Basis von [Chatterbox TTS](https://github.com/resemble-ai/chatterbox) (Resemble AI). Optimiert für deutsche Sprache; nutzbar als Kommandozeilen-Tool, als lokaler HTTP-Service und als MCP-Server für KI-Assistenten.
Find a file
dschlueter d1971049ce Add HTTP service, MCP adapter, systemd autostart; fix bugs and docs
- chatterbox_cli_v4.py: cooperative stop/interrupt via threading.Event;
  fix force_split_sentence (word boundary instead of mid-word cut);
  fix synthesize_streaming normalization order (split before preprocess)
- tts_service.py: FastAPI service with job queue, model cache, worker thread;
  LAN-accessible on 0.0.0.0:9999; audio_device default None (auto)
- mcp_adapter.py: MCP adapter (stdio + streamable-http) wrapping REST API;
  update docstring and default TTS_URL to port 9999
- requirements.txt: add fastapi, uvicorn, httpx, mcp
- README.md, BEDIENUNGSANLEITUNG.md: document service, MCP, AI integrations
  (Claude, Ollama, Open WebUI, llama.cpp, Home Assistant), systemd autostart
- CLAUDE.md: reflect current architecture (service + adapter now implemented)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 10:19:00 +02:00
.gitignore Erweiterung: Stop-Mechanismus, REST-Service und MCP-Adapter 2026-05-16 09:46:43 +02:00
BEDIENUNGSANLEITUNG.md Add HTTP service, MCP adapter, systemd autostart; fix bugs and docs 2026-05-16 10:19:00 +02:00
chatterbox_cli_v4.py Add HTTP service, MCP adapter, systemd autostart; fix bugs and docs 2026-05-16 10:19:00 +02:00
CLAUDE.md Add HTTP service, MCP adapter, systemd autostart; fix bugs and docs 2026-05-16 10:19:00 +02:00
mcp_adapter.py Add HTTP service, MCP adapter, systemd autostart; fix bugs and docs 2026-05-16 10:19:00 +02:00
README.md Add HTTP service, MCP adapter, systemd autostart; fix bugs and docs 2026-05-16 10:19:00 +02:00
requirements.txt Add HTTP service, MCP adapter, systemd autostart; fix bugs and docs 2026-05-16 10:19:00 +02:00
Trump_in_China_kurz.txt Initial commit: chatterbox TTS CLI v4 2026-05-16 08:56:50 +02:00
tts_service.py Add HTTP service, MCP adapter, systemd autostart; fix bugs and docs 2026-05-16 10:19:00 +02:00

chatterbox-tts-cli

Ein lokaler Text-to-Speech-Assistent auf Basis von Chatterbox TTS (Resemble AI). Optimiert für deutsche Sprache; nutzbar als Kommandozeilen-Tool, als lokaler HTTP-Service und als MCP-Server für KI-Assistenten.

Features

  • Satz-für-Satz-Ausgabe — gibt den ersten Satz aus, während die nächsten bereits generiert werden; minimale Latenz
  • Lückenlose Audiowiedergabe — Callback-basierter OutputStream; keine Unterbrechungen zwischen Sätzen
  • Geschwindigkeitsanpassung — pitch-erhaltende Zeitstreckung via pyrubberband (R3-Engine); --speed 0.52.0
  • Voice Cloning — optionale WAV-Referenz für Akzent und Klang
  • Mehrsprachig — Deutsch, Englisch und 20+ weitere Sprachen via ChatterboxMultilingualTTS
  • Deutsche Textnormalisierung — Abkürzungen (ARD → „Ah Er De"), Uhrzeiten (14:58 → „vierzehn Uhr achtundfünfzig"), Jahreszahlen, Einheiten, Aussprache-Wörterbuch
  • HTTP-Service — FastAPI-Service mit Job-Queue, Stop/Interrupt, Status-Endpunkt
  • MCP-Adapter — direkte Integration in Claude Code, Claude Desktop und andere MCP-Hosts
  • Systemd-Autostart — Service startet automatisch beim Login

Systemvoraussetzungen

  • Python 3.11+
  • CUDA-GPU empfohlen (RTX 3070 oder besser; CPU möglich, aber langsam)
  • Linux mit PipeWire oder PulseAudio
  • rubberband-cli für Geschwindigkeitsanpassung:
    sudo apt install rubberband-cli
    

Installation

# 1. Conda-Umgebung
conda create -n chatterbox python=3.11
conda activate chatterbox

# 2. PyTorch mit CUDA (Beispiel CUDA 12.4)
pip install torch torchaudio --index-url https://download.pytorch.org/whl/cu124

# 3. Alle Abhängigkeiten
pip install -r requirements.txt

Beim ersten Start mit --lang de werden Modelle automatisch heruntergeladen (~23 GB, ~/.cache/huggingface/).


Kommandozeilen-CLI

conda activate chatterbox

# Deutschen Text vorlesen
python chatterbox_cli_v4.py --lang de --input text.txt

# Mit Voice Cloning
python chatterbox_cli_v4.py --lang de --voice stimme.wav --input text.txt

# Text direkt übergeben
python chatterbox_cli_v4.py --lang en --text "Hello, how are you?"

# Langsamer sprechen (pitch bleibt gleich)
python chatterbox_cli_v4.py --lang de --speed 0.85 --input text.txt

# Nur speichern, nicht abspielen
python chatterbox_cli_v4.py --lang de --no-play --output ausgabe.wav --input text.txt

# Aussprache-Wörterbuch
python chatterbox_cli_v4.py --lang de --pronunciation-dict aussprache.json --input text.txt

CLI-Optionen

Option Standard Beschreibung
--text TEXT Text direkt als Argument
--input DATEI UTF-8-Textdatei
--lang CODE de Sprachcode (de, en, fr, es, …)
--voice DATEI.wav Referenz-WAV für Voice Cloning (1030 s)
--speed N 1.0 Wiedergabegeschwindigkeit (0.52.0)
--audio-device pulse Ausgabegerät (z. B. pulse, default)
--t3-model v3 Multilingual-Modell: v3 oder v2
--acronym-mode german Akronym-Modus: german, space, period_space
--pronunciation-dict JSON-Datei mit Aussprache-Substitutionen
--save nein WAV-Datei speichern
--output DATEI.wav Ausgabepfad (impliziert --save)
--no-play Nicht live abspielen
--no-sentence-mode Größere Chunks statt satzweise
--stream Streaming-Modus (experimentell)
--no-progress Weniger Konsolenausgabe
--debug-delay N 0 Pause vor jedem Satz (zum Testen)
--stop Laufende Ausgabe abbrechen

HTTP-Service (tts_service.py)

FastAPI-Service mit Job-Queue und Worker-Thread. Startet automatisch via systemd.

# Manueller Start
uvicorn tts_service:app --host 0.0.0.0 --port 9999

# Systemd (Autostart, läuft bereits)
systemctl --user status chatterbox-tts
systemctl --user restart chatterbox-tts
journalctl --user -u chatterbox-tts -f

Endpunkte

Methode Pfad Funktion
POST /speak Text in Queue einreihen
POST /stop Ausgabe abbrechen, Queue leeren
GET /health Service-Status und Gerät
GET /status Aktueller Job, Queue-Länge, letzte Jobs
GET /voices Unterstützte Sprachen

/speak Request-Body

{
  "text": "Hallo Welt",
  "lang": "de",
  "voice": null,
  "interrupt": false,
  "speed": 1.0,
  "t3_model": "v3",
  "audio_device": null,
  "max_len": 400,
  "save_wav": false,
  "output_path": null,
  "pronunciation_dict": null
}
# Beispiel
curl -X POST http://localhost:9999/speak \
  -H "Content-Type: application/json" \
  -d '{"text": "Hallo Welt", "lang": "de"}'

# Aus dem LAN
curl -X POST http://192.168.x.x:9999/speak \
  -H "Content-Type: application/json" \
  -d '{"text": "Text aus dem Netzwerk", "lang": "de"}'

# Laufende Ausgabe unterbrechen
curl -X POST http://localhost:9999/speak \
  -d '{"text": "Wichtiger Text", "lang": "de", "interrupt": true}' \
  -H "Content-Type: application/json"

# Stoppen
curl -X POST http://localhost:9999/stop

MCP-Adapter (mcp_adapter.py)

Dünner Wrapper über die REST-API für MCP-fähige Hosts.

# stdio-Modus (Claude Code / Claude Desktop)
python mcp_adapter.py --stdio

# HTTP-Modus (andere MCP-Clients, Port 8001)
python mcp_adapter.py

# Anderen TTS-Service ansprechen
TTS_URL=http://192.168.1.10:9999 python mcp_adapter.py --stdio

MCP-Tools

Tool Parameter Funktion
speak text, lang, voice, interrupt, speed Text ausgeben
stop Ausgabe stoppen
get_status Aktuellen Job abfragen
list_voices Sprachen auflisten

Claude Code Konfiguration

Bereits eingerichtet via claude mcp add --scope user. Zur manuellen Einrichtung:

claude mcp add --scope user chatterbox-tts \
  /home/dschlueter/miniforge3/envs/chatterbox/bin/python \
  /home/dschlueter/chatterbox-tts-cli/mcp_adapter.py --stdio

Claude Desktop (~/.config/claude/claude_desktop_config.json)

{
  "mcpServers": {
    "chatterbox-tts": {
      "command": "/home/dschlueter/miniforge3/envs/chatterbox/bin/python",
      "args": ["/home/dschlueter/chatterbox-tts-cli/mcp_adapter.py", "--stdio"]
    }
  }
}

Integration mit KI-Tools

Claude Code / Claude Desktop — MCP (fertig eingerichtet)

Claude kann direkt die Tools speak, stop, get_status und list_voices aufrufen. Kein weiterer Setup nötig.

Ollama (llama3.2, qwen2.5, mistral-nemo u. a.)

Modelle mit Tool-Support können den REST-Service über Function Calling ansprechen:

import ollama, httpx

tools = [{
    "type": "function",
    "function": {
        "name": "speak",
        "description": "Text als Sprache ausgeben",
        "parameters": {
            "type": "object",
            "properties": {
                "text": {"type": "string"},
                "lang": {"type": "string", "default": "de"},
                "speed": {"type": "number", "default": 1.0},
            },
            "required": ["text"],
        },
    },
}]

resp = ollama.chat(model="qwen2.5", messages=[{"role": "user", "content": "..."}], tools=tools)

for call in resp.message.tool_calls or []:
    if call.function.name == "speak":
        httpx.post("http://127.0.0.1:9999/speak", json=call.function.arguments)

Open WebUI

Im Open-WebUI-Menü unter Tools eine neue Python-Klasse anlegen:

import requests

class Tools:
    def speak(self, text: str, lang: str = "de") -> str:
        """Text als Sprache ausgeben."""
        r = requests.post("http://127.0.0.1:9999/speak",
                          json={"text": text, "lang": lang}, timeout=10)
        return r.json().get("job_id", "error")

    def stop(self) -> str:
        """Laufende Sprachausgabe stoppen."""
        requests.post("http://127.0.0.1:9999/stop", timeout=5)
        return "stopped"

LM Studio

LM Studio bietet einen OpenAI-kompatiblen Endpunkt. Die Tool-Definition entspricht dem Ollama-Beispiel oben; der Client wechselt lediglich auf die LM-Studio-URL.

llama.cpp (Server-Modus)

llama.cpp mit --jinja unterstützt Function Calling, ruft aber nicht selbst HTTP-Endpoints auf. Benötigt eine Middleware (z. B. das Ollama-Beispiel oben), die generierte Tool-Calls abfängt und an /speak weiterleitet.

Home Assistant

# configuration.yaml
rest_command:
  tts_speak:
    url: "http://192.168.x.x:9999/speak"
    method: POST
    content_type: "application/json"
    payload: '{"text": "{{ text }}", "lang": "de"}'

  tts_stop:
    url: "http://192.168.x.x:9999/stop"
    method: POST

Aufruf in einer Automation:

service: rest_command.tts_speak
data:
  text: "Die Waschmaschine ist fertig."

Node-RED / n8n

HTTP-Request-Node direkt auf POST http://<host>:9999/speak mit JSON-Body. Kein weiterer Setup nötig.

Pi (Inflection AI)

Keine Tool-API verfügbar — direkte Integration nicht möglich.


Aussprache-Wörterbuch

{
  "Xi Jinping": "Schi Dschinping",
  "Putin": "Pjutin",
  "Seoul": "Söul"
}
python chatterbox_cli_v4.py --lang de \
  --pronunciation-dict aussprache.json \
  --input nachricht.txt

Bekannte Einschränkungen

  • Wortbetonung lässt sich nicht steuern — kein SSML. Abhilfe: Voice-Referenz mit gewünschter Betonung.
  • Laufendes model.generate() kann nicht mid-call abgebrochen werden (Python-Thread-Grenzen); Stop greift am nächsten Chunk-Beginn.
  • Chinesische/japanische Namen werden phonetisch angenähert.

Lizenz

MIT — dieses Skript. Das Chatterbox-Modell: MIT-Lizenz (Resemble AI). Modellgewichte: CC BY-NC 4.0.