Turning audio off has never produced -an through audioArgs #198

Closed
opened 2026-09-02 12:46:26 +00:00 by JMR-dev · 0 comments
JMR-dev commented 2026-09-02 12:46:26 +00:00 (Migrated from github.com)

Wave 4, filed from a coverage read on main @ 54ca2dd, 2026-09-02. The shared filter note is on #194.

Turning audio off has never produced -an

app/src/main/java/org/libremediaconverter/ffmpeg/FFmpegCommandBuilder.kt:181
private fun audioArgs(plan: ConversionPlan): List<String> = when (val audio = plan.audio) {
    AudioPlan.Drop -> listOf("-an")      // <- ci == 0
    AudioPlan.Copy -> listOf("-c:a", "copy")
    is AudioPlan.Encode -> ...
}

The arm is selected by nothing in the suite.

The near-miss

FFmpegCommandBuilderTest.kt:211 does assert -an — but it comes from the GIF image path (FFmpegCommandBuilder.kt:79/:90), which emits -an directly and never reaches audioArgs. So the constant is pinned and the arm that produces it for an ordinary conversion is not. Two sites, one string, one tested.

It is a live path, not defensive code

AdvancedPicker renders all of AudioCodec.entries (ConverterScreen.kt:495), which includes NONE; ContainerCapabilities.validate permits audio-off whenever the input has video; and MKV, or QualityTier.BEST, routes the job to FFmpeg. "Convert this MKV and drop the soundtrack" is a thing a user can do today.

The work

One test in FFmpegCommandBuilderTest, which already has a cmd(spec: OutputSpec, …) overload — the fixture is OutputSpec(Container.MKV, VideoCodec.H264, AudioCodec.NONE).

Assert both halves: the command carries -an, and it carries no -c:a. The second is what distinguishes "audio dropped" from "audio dropped and also encoded", and the else -> aac arm below is close enough to make that worth stating.

Acceptance: the mutation that must go red

Replace the Drop arm with emptyList(). Then, separately, delete the arm so Drop falls through to else -> listOf("-c:a", "aac", "-b:a", "192k") — the "no -c:a" assertion must catch that one. Restore, confirm green.

_Wave 4, filed from a coverage read on `main` @ `54ca2dd`, 2026-09-02. The shared filter note is on #194._ ## Turning audio off has never produced `-an` ``` app/src/main/java/org/libremediaconverter/ffmpeg/FFmpegCommandBuilder.kt:181 ``` ```kotlin private fun audioArgs(plan: ConversionPlan): List<String> = when (val audio = plan.audio) { AudioPlan.Drop -> listOf("-an") // <- ci == 0 AudioPlan.Copy -> listOf("-c:a", "copy") is AudioPlan.Encode -> ... } ``` The arm is selected by nothing in the suite. ## The near-miss `FFmpegCommandBuilderTest.kt:211` does assert `-an` — but it comes from the **GIF image path** (`FFmpegCommandBuilder.kt:79`/`:90`), which emits `-an` directly and never reaches `audioArgs`. So the constant is pinned and the arm that produces it for an ordinary conversion is not. Two sites, one string, one tested. ## It is a live path, not defensive code `AdvancedPicker` renders all of `AudioCodec.entries` (`ConverterScreen.kt:495`), which includes `NONE`; `ContainerCapabilities.validate` permits audio-off whenever the input has video; and MKV, or `QualityTier.BEST`, routes the job to FFmpeg. "Convert this MKV and drop the soundtrack" is a thing a user can do today. ## The work One test in `FFmpegCommandBuilderTest`, which already has a `cmd(spec: OutputSpec, …)` overload — the fixture is `OutputSpec(Container.MKV, VideoCodec.H264, AudioCodec.NONE)`. Assert **both halves**: the command carries `-an`, and it carries no `-c:a`. The second is what distinguishes "audio dropped" from "audio dropped and also encoded", and the `else -> aac` arm below is close enough to make that worth stating. ## Acceptance: the mutation that must go red Replace the `Drop` arm with `emptyList()`. Then, separately, delete the arm so `Drop` falls through to `else -> listOf("-c:a", "aac", "-b:a", "192k")` — the "no `-c:a`" assertion must catch that one. Restore, confirm green.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: JMR-dev/LibreMediaConverter#198