4.4 KiB
4.4 KiB
Installation
Docker Install
curl -fsSL https://get.Docker.com -o get-Docker.shsudo sh get-Docker.shsudo usermod -aG docker $USERnewgrp docker
Pfade
- Anlegen des Ordners:
mkdir -p ~/vosk-mqtt - Reinwechseln:
cd /home/pi/vosk-mqtt/ - Dockerfile anlegen:
nano Dockerfileund 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"]
- Python-Skript anlegen:
nano stt_mqtt.pyund 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