Found during review of #64 (Concatenate Videos preserves audio). Not a regression — the code works against the ffmpeg binary we ship — but it is a latent fragility worth removing.
What
invokeai/app/util/video_audio.py, extract_audio_pcm() distinguishes "this container has no audio track" (a normal condition — Wan clips present this way) from "ffmpeg genuinely failed" by substring-matching ffmpeg's English error text:
if proc.returncode != 0:
stderr = proc.stderr.decode("utf-8", errors="replace")
# ffmpeg's phrasing for an input with no audio track ("Output file #0 does not
# contain any stream" / newer "does not contain any stream" variants).
if "does not contain any stream" in stderr:
return None
raise AudioExtractionError(...)
Why it matters
If that phrasing changes across ffmpeg versions, the branch stops matching and a silent input video raises AudioExtractionError instead of returning None. Callers treat None as "no audio, carry on", so the failure mode is that concatenating or trimming a silent clip starts erroring out — for a video that is perfectly valid.
The comment already hints the wording has moved once ("newer ... variants").
Today this is stable in practice because _ffmpeg_exe() resolves to imageio_ffmpeg.get_ffmpeg_exe(), a pinned bundled binary. The exposure is that IMAGEIO_FFMPEG_EXE lets a user point at a distro ffmpeg of any version or locale.
Possible fixes
- Probe for an audio stream first (
ffprobe -select_streams a) and skip the decode when there is none — decides on structure rather than on prose.
- Or map the audio stream optionally (
-map 0:a:0?) so ffmpeg exits 0 with no audio output, and let the existing if n == 0: return None check handle it.
Either removes the dependency on error-message text. The second is a smaller change and the n == 0 guard is already there.
Scope
invokeai/app/util/video_audio.py only. Low priority.
Found during review of #64 (Concatenate Videos preserves audio). Not a regression — the code works against the ffmpeg binary we ship — but it is a latent fragility worth removing.
What
invokeai/app/util/video_audio.py,extract_audio_pcm()distinguishes "this container has no audio track" (a normal condition — Wan clips present this way) from "ffmpeg genuinely failed" by substring-matching ffmpeg's English error text:Why it matters
If that phrasing changes across ffmpeg versions, the branch stops matching and a silent input video raises
AudioExtractionErrorinstead of returningNone. Callers treatNoneas "no audio, carry on", so the failure mode is that concatenating or trimming a silent clip starts erroring out — for a video that is perfectly valid.The comment already hints the wording has moved once ("newer ... variants").
Today this is stable in practice because
_ffmpeg_exe()resolves toimageio_ffmpeg.get_ffmpeg_exe(), a pinned bundled binary. The exposure is thatIMAGEIO_FFMPEG_EXElets a user point at a distro ffmpeg of any version or locale.Possible fixes
ffprobe -select_streams a) and skip the decode when there is none — decides on structure rather than on prose.-map 0:a:0?) so ffmpeg exits 0 with no audio output, and let the existingif n == 0: return Nonecheck handle it.Either removes the dependency on error-message text. The second is a smaller change and the
n == 0guard is already there.Scope
invokeai/app/util/video_audio.pyonly. Low priority.