""" Thin wrappers around ffmpeg/ffprobe subprocess calls. """ import json import subprocess def probe_duration(path: str) -> float: """Returns media duration in seconds via ffprobe.""" out = subprocess.run( ["ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "json", path], capture_output=True, text=True, check=True, ) data = json.loads(out.stdout) return float(data["format"]["duration"]) def run_ffmpeg(args: list[str], log_path: str | None = None): """Runs an ffmpeg command, raising with stderr captured on failure.""" cmd = ["ffmpeg", "-y"] + args result = subprocess.run(cmd, capture_output=True, text=True) if log_path: with open(log_path, "a") as f: f.write(" ".join(cmd) + "\n") f.write(result.stderr + "\n") if result.returncode != 0: raise RuntimeError(f"ffmpeg failed ({result.returncode}): {result.stderr[-2000:]}") return result