babysor/MockingBird · error · RuntimeError
ffprobe failed on {path}: {proc.stderr}
Error message
ffprobe failed on {path}: {proc.stderr} What it means
RuntimeError raised by probe_duration_ms when ffprobe (bundled with ffmpeg) exits non-zero while reading a media file's duration. Used before atempo time-stretching and after Kokoro TTS to get actual audio length.
Source
Thrown at skills/speak/scripts/render_timeline.py:135
if proc.returncode != 0:
raise RuntimeError(f"ffmpeg failed: {' '.join(cmd)}\n{proc.stderr}")
def ensure_ffmpeg() -> None:
if not shutil.which("ffmpeg"):
raise RuntimeError("ffmpeg not found in PATH.")
def probe_duration_ms(path: Path) -> float:
proc = subprocess.run(
[
"ffprobe", "-v", "error", "-show_entries", "format=duration",
"-of", "default=noprint_wrappers=1:nokey=1", str(path),
],
capture_output=True, text=True,
)
if proc.returncode != 0:
raise RuntimeError(f"ffprobe failed on {path}: {proc.stderr}")
return float(proc.stdout.strip()) * 1000
def normalize_duration_pad_trim(inp: Path, outp: Path, target_ms: int) -> None:
"""Pad short audio then trim to exact target duration (Noiz backend)."""
sec = target_ms / 1000.0
_run_ff([
"ffmpeg", "-y", "-i", str(inp),
"-af", f"apad=pad_dur={sec:.3f}",
"-t", f"{sec:.3f}", str(outp),
])
def normalize_duration_atempo(inp: Path, outp: Path, target_ms: int) -> None:
"""Use atempo to stretch/compress audio to target duration (Kokoro backend)."""
actual_ms = probe_duration_ms(inp)
if actual_ms <= 0:
normalize_duration_pad_trim(inp, outp, target_ms)View on GitHub (pinned to 28dc5e14f1)
Solutions
- Run: ffprobe -v error -show_entries format=duration file.wav manually to see the error
- Validate the file is real audio (check size > 0 and file type) before probing
- Re-generate the offending audio segment
- Ensure ffprobe is installed and on PATH (comes with ffmpeg)
Example fix
# before
ms = probe_duration_ms(seg_path)
# after
if not seg_path.exists() or seg_path.stat().st_size == 0:
raise RuntimeError(f"empty segment: {seg_path}")
ms = probe_duration_ms(seg_path) Defensive patterns
Strategy: validation
Validate before calling
p = Path(seg)
assert p.exists() and p.stat().st_size > 0, f'bad audio file: {p}' Try / catch
try:
ms = probe_duration_ms(p)
except RuntimeError:
ms = -1.0 # re-synthesize segment later Prevention
- Check file size before probing
- Regenerate truncated segments
- Keep ffmpeg/ffprobe versions in sync
When it happens
Trigger: Pointing ffprobe at a non-media file, a corrupt/truncated audio file (e.g. incomplete TTS download), an unreadable path, or a format the installed ffprobe cannot parse.
Common situations: TTS output was written from an error response body instead of audio, partial file from a killed process, or zero-byte file from a failed upstream request.
Related errors
- ffmpeg failed: {' '.join(cmd)}\n{proc.stderr}
- No segments to mix.
- Package 'webrtcvad' not found. This package enables noise re
- Package 'webrtcvad' not found. This package enables noise re
- Both increase only and decrease only are set
AI-assisted analysis of babysor/MockingBird@28dc5e14f1 (2026-08-27).
Data as JSON: /api/errors/eb13644df19efea9.
Report an issue: GitHub.