Push-to-talk Vosk extension for Pi with live editor transcription
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

61 lines
1.6 KiB

#!/usr/bin/env python3
import json
import sys
from pathlib import Path
try:
from vosk import Model, KaldiRecognizer, SetLogLevel
except Exception as e:
print(json.dumps({"type": "fatal", "error": f"Python package 'vosk' non disponibile: {e}"}), flush=True)
raise SystemExit(1)
def emit(obj: dict):
print(json.dumps(obj, ensure_ascii=False), flush=True)
def main() -> int:
if len(sys.argv) < 2:
emit({"type": "fatal", "error": "Uso: vosk_daemon.py <model_path>"})
return 1
model_path = Path(sys.argv[1]).expanduser()
if not model_path.exists():
emit({"type": "fatal", "error": f"Modello Vosk non trovato: {model_path}"})
return 1
SetLogLevel(-1)
model = Model(str(model_path))
rec = KaldiRecognizer(model, 16000)
last_partial = ""
emit({"type": "ready"})
while True:
data = sys.stdin.buffer.read(4000)
if not data:
break
if rec.AcceptWaveform(data):
result = json.loads(rec.Result())
text = (result.get("text") or "").strip()
if text:
emit({"type": "final", "text": text})
last_partial = ""
else:
result = json.loads(rec.PartialResult())
partial = (result.get("partial") or "").strip()
if partial != last_partial:
last_partial = partial
emit({"type": "partial", "text": partial})
final = json.loads(rec.FinalResult())
text = (final.get("text") or "").strip()
if text:
emit({"type": "final", "text": text})
return 0
if __name__ == "__main__":
raise SystemExit(main())