Skip to content

fix(relay): stop routing audio containers through the video validator - #5950

Open
Chessing234 wants to merge 4 commits into
block:mainfrom
Chessing234:fix/m4a-not-video
Open

fix(relay): stop routing audio containers through the video validator#5950
Chessing234 wants to merge 4 commits into
block:mainfrom
Chessing234:fix/m4a-not-video

Conversation

@Chessing234

Copy link
Copy Markdown
Contributor

Addresses the first "minimum safe behavior" bullet of #5752 — the misleading error. It does not add audio support.

should_stream_as_video routed every ISO-BMFF container into the streaming video path. An M4A voice memo is ISO-BMFF, so an Apple Voice Memo reached validate_video_file and a normal (non-fast-start) recording died in check_moov_before_mdat with:

422 moov atom not at front of file (not fast-start)

That names an internal layout detail the user can do nothing about, and it isn't even the real obstacle — the same validator goes on to require a video track, which an audio-only file will never have. Rewriting the container to put moov first would move the failure, not fix it.

Audio-branded containers now take the generic file path, which already refuses audio explicitly, so the answer becomes:

415 disallowed content type: audio/m4a

That is what "Buzz has no audio pipeline yet" honestly looks like, and 415 is the correct status for it.

Why a new predicate. Nothing existing could tell the two apart. looks_like_iso_bmff is true for both, and looks_like_mp4_iso_bmff consults the compatible brand list — where an Apple Voice Memo carries isom and mp42, so it reads as MP4. Only the major brand declares what the container actually holds, which is what looks_like_audio_iso_bmff (first commit) reads.

Video routing is unchanged, including the proprietary-major-brand case the existing proprietary_iso_bmff_brand_still_uses_video_pipeline test pins.

Left for the follow-up the issue also asks for: the actual audio pipeline (remux/sanitize/strip metadata), and the mobile-side PathNotFoundException on retry, which is a Flutter change I can't run the suite for locally.

Verified locally on the pinned 1.95.0 toolchain:

  • cargo test -p buzz-media --lib121 passed, 0 failed (117 before, plus the 4 new)
  • cargo test -p buzz-relay --lib api::media — 29 passed, plus the 2 new; the 6 failures there are pre-existing and identical on main (they need a database), and buzz-relay is not among the crates just test-unit runs
  • cargo clippy --workspace --all-targets -- -D warnings — clean
  • cargo fmt --all -- --check — clean

Note: I'm an outside contributor, so the workflow runs here sit at action_required until a maintainer approves them; only the DCO check reports on its own.

`looks_like_iso_bmff` answers "is this an `ftyp` container", which is true of
an MP4 video and of an M4A voice memo alike. Nothing could tell the two
apart: `looks_like_mp4_iso_bmff` consults the compatible-brand list, and an
Apple Voice Memo carries `isom` and `mp42` there, so it reads as MP4.

Add `looks_like_audio_iso_bmff`, which reads the *major* brand — the one
field that actually declares the container's content — against the Apple and
Flash audio brands.

Pure predicate, no caller yet.

Signed-off-by: Taksh <takshkothari09@gmail.com>
`should_stream_as_video` sent every ISO-BMFF container down the streaming
video path. An M4A voice memo is ISO-BMFF, so an Apple Voice Memo reached
`validate_video_file`, where a normal (non-fast-start) recording fails
`check_moov_before_mdat` with

    422 moov atom not at front of file (not fast-start)

That message describes an internal layout detail the user cannot act on, and
it is not even the real obstacle: the same validator goes on to require a
video track, which an audio-only file will never have. Rewriting the file to
put moov first would move the failure, not fix it (block#5752).

Route audio-branded containers to the generic path instead, which already
refuses audio explicitly and answers

    415 disallowed content type: audio/m4a

That is what "Buzz has no audio pipeline yet" honestly looks like, and 415 is
the right status for it. Video routing is unchanged, including the
proprietary-brand case the existing test pins.

Signed-off-by: Taksh <takshkothari09@gmail.com>
@Chessing234
Chessing234 requested a review from a team as a code owner August 15, 2026 12:51

@themiguelamador themiguelamador left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The major-brand shortcut is not a sound proxy for track contents. The MP4 Registration Authority defines M4A as an iTunes MPEG-4 audio brand that can contain audio, video, 3G text, and chapter tracks; M4B can contain those tracks too. As written, any valid video-bearing file with either major brand skips video validation and is rejected by the generic path as audio. That regresses an accepted video based only on its compatibility declaration.

I pushed a complete fix in 52cbcd293:

  • keep all ISO-BMFF uploads on the bounded streaming path;
  • classify the completed container from parsed track types before applying video-only fast-start and metadata requirements;
  • return 415 audio/mp4 for an actual audio-only, mdat-first Voice Memo;
  • preserve acceptance and validation of an M4A -branded file that actually contains video;
  • remove the unregistered/over-broad audio-brand list and its public helper.

Verification:

  • cargo fmt --check — pass
  • cargo test -p buzz-media --lib — 119 passed
  • exact relay tests for M4A and proprietary-brand routing — pass
  • cargo clippy -p buzz-media -p buzz-relay --lib -- -D warnings — pass
  • broader relay media module — 28 infrastructure-free tests passed; 6 existing DB-backed tests could not run because the local Postgres instance has no buzz role

Authoritative brand registry: https://mp4ra.org/registered-types/brands

…t-start

Review is right that a major-brand shortcut is not a sound proxy for track
contents. MP4RA registers `M4A ` as an iTunes MPEG-4 audio brand that may
still carry audio, video, 3G text and chapter tracks, and `M4B ` likewise. A
brand is a compatibility declaration, not an inventory.

The validator already knew how to answer this correctly — the track loop
returns `DisallowedContentType("audio/mp4")` (a 415) when it finds audio and
no video. What went wrong is ordering: `check_moov_before_mdat` ran as the
very first statement, so a Voice Memo, which is never written fast-start,
failed there with "moov atom not at front of file" and never reached the
classification. That is a 422 about a requirement which does not apply to a
file with no video in it.

Classification now runs first, from the parsed track types, and the two
video-only requirements — fast-start and metadata-free — run after it. The
mp4 crate parses the whole file regardless of atom order, so an mdat-first
container reaches the track scan fine; the size guard still bounds the parse.

An `M4A `-branded file that really does contain video is unaffected: it
classifies as video, is validated as one, and still has to be fast-start.

Verified the regression fails on the old ordering: reinstating the leading
`check_moov_before_mdat` turns the new test's result into `Err(MoovNotAtFront)`.

- `cargo test -p buzz-media --lib` — 121 passed
- `cargo fmt --all -- --check`

Signed-off-by: Taksh <takshkothari09@gmail.com>
Review: routing audio-branded containers away from the streaming path rejects
a genuine video on its compatibility declaration alone. Any valid video-bearing
file with an `M4A `/`M4B ` major brand would have skipped video validation and
then been refused by the generic path as audio — a regression against files
that are accepted today.

`should_stream_as_video` goes back to admitting every ISO-BMFF container. With
the previous commit the validator classifies from parsed tracks, so an
audio-only container still gets the honest `415 audio/mp4` and a video-bearing
one is still validated as video. The routing layer no longer needs to guess.

The brand list itself is gone along with its public helper: several of its
entries (`M4P `, `M4R `, `F4A `, `F4B `, `mp4a`) are not registered ISO-BMFF
brands at all, and the registered ones do not mean what the list claimed.

- `cargo test -p buzz-media --lib` — 121 passed
- relay media module — 29 passed; the same 6 DB-backed tests cannot run here,
  the local Postgres has no `buzz` role (pre-existing, unrelated to this diff)
- `cargo clippy -p buzz-media -p buzz-relay --lib -- -D warnings`
- `cargo fmt --all -- --check`

Signed-off-by: Taksh <takshkothari09@gmail.com>
@Chessing234

Copy link
Copy Markdown
Contributor Author

You're right and the brand shortcut is gone. 52cbcd293 wasn't reachable (Complear/buzz 404s), so this is rebuilt from your description; it lands as two commits.

The useful thing I found reimplementing it: the validator already answered this correctly. The track loop returns DisallowedContentType("audio/mp4") — a 415 — when it finds audio and no video. What was wrong was ordering. check_moov_before_mdat ran as the very first statement of validate_video_file, so a Voice Memo, which is never fast-start, failed there and never reached the classification. That's how the moov 422 came about.

So the fix is the one you described, and it needed no new classification logic:

  • should_stream_as_video admits every ISO-BMFF container again — the routing layer stops guessing;
  • classification runs first, from parsed track types;
  • fast-start and metadata-free run after it, as the video-only requirements they are;
  • the brand list and looks_like_audio_iso_bmff are removed. Worth noting several of its entries (M4P , M4R , F4A , F4B , mp4a) aren't registered ISO-BMFF brands at all.

An M4A -branded file that really contains video classifies as video, is validated as one, and is still required to be fast-start — there's a test for each of those.

I checked the regression actually regresses: reinstating the leading check_moov_before_mdat turns the new audio-only test's result into Err(MoovNotAtFront), and removing it again gives Err(DisallowedContentType("audio/mp4")).

Verification:

  • cargo test -p buzz-media --lib — 121 passed
  • cargo test -p buzz-relay --lib api::media — 29 passed; the same 6 DB-backed tests you saw can't run here either (role "buzz" does not exist), pre-existing and untouched by this diff
  • cargo clippy -p buzz-media -p buzz-relay --lib -- -D warnings
  • cargo fmt --all -- --check

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants