You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

56 lines
1.8 KiB
Python

#!/usr/bin/env python3
"""ASR local para o Italiano Vivo via faster-whisper.
O proxy LiteLLM (10.8.0.1:4000) nao aceita partes de audio no chat/completions
(qwen omni devolve 400 "Invalid video file" / "provided URL does not appear to be valid"),
entao a transcricao roda aqui e o server Node repassa so o texto para o juiz LLM.
Uso:
python asr_whisper.py <audio_path> [--model small] [--json]
Imprime o texto transcrito (ou JSON com segments/timing com --json).
Idempotente: baixa o modelo uma vez e usa cache local do HuggingFace.
"""
import argparse
import json
import sys
def main() -> int:
ap = argparse.ArgumentParser(description="Transcricao IT/PT com faster-whisper")
ap.add_argument("audio", help="caminho do arquivo de audio (mp3/wav/webm)")
ap.add_argument("--model", default="small", help="tiny|base|small|medium (default small)")
ap.add_argument("--lang", default=None, help="forcar idioma, ex.: it")
ap.add_argument("--json", action="store_true", dest="as_json")
args = ap.parse_args()
from faster_whisper import WhisperModel
model = WhisperModel(args.model, device="cpu", compute_type="int8")
segments, info = model.transcribe(
args.audio, language=args.lang, beam_size=5, vad_filter=True
)
parts = []
seg_list = []
for s in segments:
parts.append(s.text.strip())
seg_list.append({"start": round(s.start, 2), "end": round(s.end, 2), "text": s.text.strip()})
text = " ".join(p for p in parts if p).strip()
if args.as_json:
print(json.dumps({
"text": text,
"language": info.language,
"language_probability": round(float(info.language_probability), 3),
"segments": seg_list,
}, ensure_ascii=False))
else:
print(text)
return 0 if text else 2
if __name__ == "__main__":
sys.exit(main())