OshoDiscourse-SearchEngine / app /audio_utils.py
kumarakkiy's picture
Upload 143 files
4cdc522 verified
Raw
History Blame Contribute Delete
1.88 kB
"""ffmpeg helpers: locate the binary and normalize audio to 16 kHz mono WAV.
Whisper/WhisperX expect 16 kHz mono; normalizing once up front also makes decoding of
exotic inputs (m4a/opus/wma/video containers) reliable. We always call ffmpeg by an
absolute path (missing-ffmpeg-on-PATH is the #1 cause of "the audio query does nothing").
"""
from __future__ import annotations
import shutil
import subprocess
import sys
from pathlib import Path
from typing import Optional
from app.config import get_config
AUDIO_EXTS = {
".mp3", ".wav", ".m4a", ".aac", ".flac", ".ogg", ".opus",
".wma", ".mp4", ".webm", ".mkv", ".mov", ".3gp",
}
_FFMPEG: Optional[str] = None
def find_ffmpeg() -> str:
"""Locate ffmpeg: PATH first, then a bundled project ``bin/ffmpeg.exe``."""
global _FFMPEG
if _FFMPEG:
return _FFMPEG
exe = shutil.which("ffmpeg")
if not exe:
binname = "ffmpeg.exe" if sys.platform == "win32" else "ffmpeg"
bundled = get_config().root / "bin" / binname
if bundled.exists():
exe = str(bundled)
if not exe:
raise FileNotFoundError(
"ffmpeg not found. Install it (winget install Gyan.FFmpeg) or place ffmpeg.exe in ./bin/."
)
_FFMPEG = exe
return exe
def normalize_to_wav(src: str | Path, dst: str | Path) -> Path:
"""Decode any input to 16 kHz mono 16-bit PCM WAV at ``dst``."""
dst = Path(dst)
dst.parent.mkdir(parents=True, exist_ok=True)
cmd = [
find_ffmpeg(), "-y", "-hide_banner", "-loglevel", "error",
"-i", str(src), "-vn", "-ac", "1", "-ar", "16000",
"-c:a", "pcm_s16le", "-f", "wav", str(dst),
]
proc = subprocess.run(cmd, capture_output=True, text=True)
if proc.returncode != 0 or not dst.exists():
raise RuntimeError(f"ffmpeg failed for {src}: {proc.stderr.strip()[:500]}")
return dst