Initial commit: Nat20 Notes — TTRPG session transcription & summarization
This commit is contained in:
35
backend/app/pipeline/audio.py
Normal file
35
backend/app/pipeline/audio.py
Normal file
@@ -0,0 +1,35 @@
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
from ..errors import AudioExtractionError
|
||||
from ..logging_config import get_logger
|
||||
|
||||
log = get_logger(__name__)
|
||||
|
||||
|
||||
def extract_audio(video_path: Path, audio_path: Path) -> Path:
|
||||
"""Extract 16kHz mono wav from any video/audio container."""
|
||||
if not video_path.exists():
|
||||
raise AudioExtractionError(f"Uploaded file not found on disk at {video_path}. It may not have finished uploading, or the upload volume isn't mounted correctly.")
|
||||
|
||||
if audio_path.exists():
|
||||
log.info("Audio already extracted at %s, skipping", audio_path)
|
||||
return audio_path
|
||||
|
||||
log.info("Extracting audio: %s -> %s", video_path, audio_path)
|
||||
result = subprocess.run(
|
||||
[
|
||||
"ffmpeg", "-y", "-i", str(video_path),
|
||||
"-vn", "-acodec", "pcm_s16le", "-ar", "16000", "-ac", "1",
|
||||
str(audio_path),
|
||||
],
|
||||
capture_output=True, text=True,
|
||||
)
|
||||
if result.returncode != 0:
|
||||
# surface ffmpeg's own error line rather than the whole verbose log
|
||||
stderr_tail = "\n".join(result.stderr.strip().splitlines()[-5:])
|
||||
raise AudioExtractionError(
|
||||
f"ffmpeg failed to extract audio (exit code {result.returncode}). "
|
||||
f"This usually means the file is corrupt or not a supported format. Last output:\n{stderr_tail}"
|
||||
)
|
||||
return audio_path
|
||||
Reference in New Issue
Block a user