Make Media3 write the container and codec it was asked for #2

Merged
JMR-dev merged 2 commits from fix/media3-honours-output-format into main 2026-08-22 12:23:58 +00:00
JMR-dev commented 2026-08-22 12:08:35 +00:00 (Migrated from github.com)

Media3Engine never called setMuxerFactory or setAudioMimeType, and built a bare EditedMediaItem, so it always produced MP4 with an H.265 video track. The router meanwhile sends it WebM, Ogg, WAV and AAC-ADTS jobs, plus audio-only M4A, Opus and WAV — and ConversionWorker.media3MimeType() mapped VideoCodec.NONE through its else branch to VIDEO_H265.

The visible result: "extract audio to M4A" transcoded the video to HEVC and named the file .m4a. Nothing failed, and nothing caught it, because Media3EngineTest had no audio-only case at all.

What changed

media3-muxer already ships WebmMuxer, OggMuxer, WavMuxer and AacMuxer; only the MP4 ones come pre-wrapped as a Muxer.Factory. Media3Muxers supplies the rest. Their reported sample MIME types are read from each muxer's own support check rather than assumed, because Transformer uses those lists to decide whether a track needs re-encoding.

HardwareTranscoder.transcode now takes the OutputFormat instead of a video MIME string, which is what gives the container, the audio codec and "this output has no video" somewhere to travel.

MEDIA3_CONTAINERS stops being private so a test can assert it agrees with the factories. Those two drifted once already: the router's set was right the whole time the engine was ignoring it.

Verification

  • :app:testDebugUnitTest — 71 tests green (66 existing + 5 new in Media3MuxersTest).
  • Three new instrumented cases in Media3EngineTest: audio-only M4A asserts exactly one AAC track and no video track (the regression guard for the bug above), plus RIFF and OggS header checks for WAV and Ogg.

⚠️ The instrumented tests have not been executed — the emulator segfaults on my machine (exit 139 across three AVDs and both GPU backends, environmental). This PR's CI run is the first real exercise of them. WAV and Ogg output through the new muxers are newly reachable and unproven; setAudioMimeType(AUDIO_RAW) for WAV assumes Transformer does PCM passthrough, which is plausible from the muxer's reported MIME list but not verified. If those two come back red, the honest fix is dropping WAV and OGG from MEDIA3_CONTAINERS — Media3MuxersTest will then require the matching factories to go too, which is the right coupling. runMedia3OrFallBack already catches export failures and reruns on FFmpeg, so the failure mode is "slower", not "wrong file".

🤖 Generated with Claude Code

Media3Engine never called `setMuxerFactory` or `setAudioMimeType`, and built a bare `EditedMediaItem`, so it always produced MP4 with an H.265 video track. The router meanwhile sends it WebM, Ogg, WAV and AAC-ADTS jobs, plus audio-only M4A, Opus and WAV — and `ConversionWorker.media3MimeType()` mapped `VideoCodec.NONE` through its `else` branch to `VIDEO_H265`. The visible result: **"extract audio to M4A" transcoded the video to HEVC and named the file `.m4a`.** Nothing failed, and nothing caught it, because `Media3EngineTest` had no audio-only case at all. ## What changed `media3-muxer` already ships `WebmMuxer`, `OggMuxer`, `WavMuxer` and `AacMuxer`; only the MP4 ones come pre-wrapped as a `Muxer.Factory`. `Media3Muxers` supplies the rest. Their reported sample MIME types are read from each muxer's own support check rather than assumed, because Transformer uses those lists to decide whether a track needs re-encoding. `HardwareTranscoder.transcode` now takes the `OutputFormat` instead of a video MIME string, which is what gives the container, the audio codec and "this output has no video" somewhere to travel. `MEDIA3_CONTAINERS` stops being private so a test can assert it agrees with the factories. Those two drifted once already: the router's set was right the whole time the engine was ignoring it. ## Verification - `:app:testDebugUnitTest` — 71 tests green (66 existing + 5 new in `Media3MuxersTest`). - Three new instrumented cases in `Media3EngineTest`: audio-only M4A asserts exactly one AAC track and **no video track** (the regression guard for the bug above), plus RIFF and OggS header checks for WAV and Ogg. ⚠️ **The instrumented tests have not been executed** — the emulator segfaults on my machine (exit 139 across three AVDs and both GPU backends, environmental). This PR's CI run is the first real exercise of them. WAV and Ogg output through the new muxers are newly reachable and unproven; `setAudioMimeType(AUDIO_RAW)` for WAV assumes Transformer does PCM passthrough, which is plausible from the muxer's reported MIME list but not verified. If those two come back red, the honest fix is dropping WAV and OGG from `MEDIA3_CONTAINERS` — `Media3MuxersTest` will then require the matching factories to go too, which is the right coupling. `runMedia3OrFallBack` already catches export failures and reruns on FFmpeg, so the failure mode is "slower", not "wrong file". 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.