From 228b8a46506c29d6daf69f4863b4b114a1ab937b Mon Sep 17 00:00:00 2001 From: admin Date: Mon, 8 Jun 2026 10:11:20 +0000 Subject: [PATCH] =?UTF-8?q?README.md=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..23e508a --- /dev/null +++ b/README.md @@ -0,0 +1,151 @@ +# Installation +## Docker Install +1) `curl -fsSL https://get.Docker.com -o get-Docker.sh` +2) `sudo sh get-Docker.sh` +3) `sudo usermod -aG docker $USER` +4) `newgrp docker` + +## Pfade +1) Anlegen des Ordners: `mkdir -p ~/vosk-mqtt` +2) Reinwechseln: `cd /home/pi/vosk-mqtt/` +3) Dockerfile anlegen: `nano Dockerfile` und mit folgendem Inhalt füllen: +``` +FROM python:3.11-slim + +ENV DEBIAN_FRONTEND=noninteractive + +# Audio-Bibliotheken für sounddevice/PortAudio + ALSA-Tools +# UND libatomic1 für Vosk (fehlt im slim-Image) +RUN apt-get update && apt-get install -y --no-install-recommends \ + portaudio19-dev \ + alsa-utils \ + libatomic1 \ + && rm -rf /var/lib/apt/lists/* + +# Python-Pakete: Vosk, Sounddevice, Paho-MQTT +RUN pip install --no-cache-dir \ + vosk \ + sounddevice \ + paho-mqtt + +WORKDIR /app + +# Standard-Umgebungsvariablen +ENV MQTT_HOST=mosquitto \ + MQTT_PORT=1883 \ + MQTT_TOPIC=klassengelaber \ + VOSK_LANG=de \ + DEVICE_ID=-1 + +COPY stt_mqtt.py . + +CMD ["python", "stt_mqtt.py"] +``` +4) Python-Skript anlegen: `nano stt_mqtt.py` und mit folgendem Inhalt füllen +``` +#!/usr/bin/env python3 +import os +import sys +import json +import queue + +import sounddevice as sd +from vosk import Model, KaldiRecognizer +import paho.mqtt.client as mqtt + +# --- Konfiguration aus Umgebungsvariablen --- +MQTT_HOST = os.getenv("MQTT_HOST", "localhost") +MQTT_PORT = int(os.getenv("MQTT_PORT", "1883")) +MQTT_TOPIC = os.getenv("MQTT_TOPIC", "klassengelaber") +VOSK_LANG = os.getenv("VOSK_LANG", "de") +DEVICE_ID = int(os.getenv("DEVICE_ID", "-1")) + +# Ideale Sample-Rate für Vosk (Pi-schnell) +VOSK_SAMPLERATE = 16000 + +q = queue.Queue() + + +def audio_callback(indata, frames, time, status): + """Callback wird von sounddevice für jeden Audio-Block aufgerufen.""" + if status: + print(status, file=sys.stderr) + q.put(bytes(indata)) + + +def main(): + # --- MQTT-Client aufsetzen --- + client = mqtt.Client() + client.connect(MQTT_HOST, MQTT_PORT, 60) + client.loop_start() + + # --- Audio-Device bestimmen --- + if DEVICE_ID >= 0: + device = DEVICE_ID + else: + device = None # default device + + device_info = sd.query_devices(device, "input") + native_samplerate = int(device_info["default_samplerate"]) + print(f"Native Sample-Rate des Mikrofon: {native_samplerate} Hz") + + # Wir nutzen VOSK_SAMPLERATE (16000 Hz) für Vosk. + # sounddevice konvertiert automatisch, wenn wir samplerate=VOSK_SAMPLERATE setzen. + samplerate = VOSK_SAMPLERATE + + print(f"Nutze Eingabegerät: {device_info['name']} @ {samplerate} Hz (für Vosk)") + + # --- Vosk-Modell laden --- + print(f"Lade Vosk-Modell für Sprache: {VOSK_LANG}") + model = Model(lang=VOSK_LANG) + + rec = KaldiRecognizer(model, samplerate) + + # --- Audio-Stream öffnen mit angepassten Parametern --- + # blocksize=4000 -> 4000 Samples @ 16000 Hz = 250 ms + # latency="high" -> mehr Buffer, weniger Overflow + with sd.RawInputStream( + samplerate=samplerate, + blocksize=4000, + device=device, + dtype="int16", + channels=1, + latency="high", + callback=audio_callback, + ): + print("#" * 80) + print("Live-Transkription läuft. Strg+C zum Beenden.") + print("#" * 80) + + try: + while True: + data = q.get() + if rec.AcceptWaveform(data): + # Finales Ergebnis + res = json.loads(rec.Result()) + text = res.get("text", "").strip() + if text: + print(f"FINAL: {text}") + client.publish(MQTT_TOPIC, payload=text, qos=0, retain=False) + else: + # Optional: Teil-Ergebnis + pres = json.loads(rec.PartialResult()) + ptext = pres.get("partial", "").strip() + if ptext: + print(f"PARTIAL: {ptext}", end="\r") + except KeyboardInterrupt: + print("\nStoppe…") + finally: + client.loop_stop() + + +if __name__ == "__main__": + main() +``` +## Docker build +Bauen des Container-Images imd Projektordner `docker build -t vosk-mqtt .` +## Docker run +Ausführen des Docker-Containers (ggfs. später per Systemdienst starten!) +``` +docker run --rm --name vosk-mqtt --device /dev/snd:/dev/snd --group-add audio -e MQTT_HOST=192.168.213.12 -e MQTT_PORT=1883 -e MQTT_TOPIC=fi24b/klassengelaber -e VOSK_LANG=de -e DEVICE_ID=-1 vosk-mqtt:latest +``` \ No newline at end of file