45 lines
1.6 KiB
Python
45 lines
1.6 KiB
Python
"""Exact pinned local-audio preparation fragment with its direct dependencies."""
|
|
|
|
import os
|
|
from pathlib import Path
|
|
import shutil
|
|
import subprocess
|
|
from typing import Optional
|
|
|
|
|
|
LOCAL_NATIVE_AUDIO_FORMATS = {".wav", ".aiff", ".aif"}
|
|
logger = __import__("logging").getLogger(__name__)
|
|
|
|
|
|
def _find_ffmpeg_binary() -> Optional[str]:
|
|
return shutil.which("ffmpeg")
|
|
|
|
|
|
def windows_hide_flags() -> int:
|
|
return 0
|
|
|
|
|
|
def _prepare_local_audio(file_path: str, work_dir: str) -> tuple[Optional[str], Optional[str]]:
|
|
"""Normalize audio for local CLI STT when needed."""
|
|
audio_path = Path(file_path)
|
|
if audio_path.suffix.lower() in LOCAL_NATIVE_AUDIO_FORMATS:
|
|
return file_path, None
|
|
|
|
ffmpeg = _find_ffmpeg_binary()
|
|
if not ffmpeg:
|
|
return None, "Local STT fallback requires ffmpeg for non-WAV inputs, but ffmpeg was not found"
|
|
|
|
converted_path = os.path.join(work_dir, f"{audio_path.stem}.wav")
|
|
command = [ffmpeg, "-y", "-i", file_path, converted_path]
|
|
|
|
try:
|
|
subprocess.run(command, check=True, capture_output=True, text=True, timeout=300, stdin=subprocess.DEVNULL, creationflags=windows_hide_flags())
|
|
return converted_path, None
|
|
except subprocess.TimeoutExpired:
|
|
logger.error("ffmpeg conversion timed out for %s", file_path)
|
|
return None, "Audio conversion for local STT timed out"
|
|
except subprocess.CalledProcessError as e:
|
|
details = e.stderr.strip() or e.stdout.strip() or str(e)
|
|
logger.error("ffmpeg conversion failed for %s: %s", file_path, details)
|
|
return None, f"Failed to convert audio for local STT: {details}"
|