Concatenating whole MP3 files does not make a longer MP3. Each TTS clip is a
standalone file: a small ID3v2 tag, then a first frame carrying an `Info`/`Xing`
VBR header that declares THAT CLIP's frame count. Joined raw, a player reads
clip one's header, believes the file is that long, and stops. The 6.1 MB
"episode" played for 6.9 seconds.
Caught by the operator listening to it. I had verified the byte count, the ID3
magic and a >100 KB size floor — every proxy for "this is audio" — and never
that it plays. The assertion I needed was duration, and none of the ones I wrote
could fail on this bug.
Measured on two real clips of 4.86s and 4.68s:
raw concat -> 4.86s only clip one plays
strip second clip's ID3 -> 4.86s
strip both clips' ID3 -> 4.86s the tag was never the problem
strip ID3 *and* the Info frame -> 9.53s correct
The ID3 tag is ~45 bytes and harmless. The header FRAME is what lies, and my
first attempt at a fix — scanning the joined file for `ID3` — was worse than
useless: it matched those bytes inside audio data and silently deleted half the
stream.
`strip_container` removes both from every clip, leaving pure frames a player
times from the stream itself. Real ElevenLabs output is committed as a fixture
so the test pins the actual wire format, not an approximation of it, and a
junk-input case proves a malformed clip fails the render rather than panicking.
Re-rendered the same script: 380.8s, up from 6.9s.
361 tests pass.
Co-Authored-By: Claude Opus 5 <[email protected]>