"""Audio transcription using faster-whisper (CPU-friendly).""" import logging import os from typing import Optional logger = logging.getLogger(__name__) _model = None def _get_model(): """Load and cache the faster-whisper model (loaded once per process).""" global _model if _model is None: from faster_whisper import WhisperModel model_size = os.environ.get("WHISPER_MODEL", "base") logger.info("Loading faster-whisper model: %s", model_size) _model = WhisperModel(model_size, device="cpu", compute_type="int8") logger.info("faster-whisper model loaded") return _model def transcribe_audio(audio_path: Optional[str]) -> list[dict]: """Transcribe an audio file and return timestamped segments. Returns a list of dicts with keys: start, end, text. Returns an empty list if audio_path is None. """ if audio_path is None: logger.info("No audio path provided; skipping transcription") return [] model = _get_model() logger.info("Transcribing %s", audio_path) segments_iter, _info = model.transcribe(audio_path, word_timestamps=True) segments = [] for seg in segments_iter: segments.append({ "start": seg.start, "end": seg.end, "text": seg.text.strip(), }) logger.info("Transcription complete: %d segments", len(segments)) return segments