fix(audio_mixer): stop segmented_music from halving narration volume

`_segmented_music` mixed the video's audio with the shaped music via
`amix=inputs=2`, whose default `normalize=1` scales every input by 1/inputs
(x0.5, -6 dB). Unlike `_mix` and `_full_mix`, this path has no `loudnorm` stage
afterward to re-normalize, so the narration was permanently attenuated across
the entire timeline — including the stretches where the music volume expression
evaluates to 0. A one-second music segment quietly dropped the narration by
~6 dB for the whole video.

Add `normalize=0` to the amix: the music is already scaled to `music_volume`
by the `volume` expression, so speech passes at unity. Verified with ffmpeg —
narration in a no-music region tracks the stereo/aac conversion baseline
instead of sitting 6 dB below it.
This commit is contained in:
0xDevNinja
2026-07-06 13:12:33 +05:30
parent 7fff88af3c
commit 4c10481011
2 changed files with 126 additions and 1 deletions

View File

@@ -653,7 +653,13 @@ class AudioMixer(BaseTool):
f"volume='{vol_expr}':eval=frame[music_shaped];"
f"[0:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo[speech];"
f"[music_shaped]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo[music_fmt];"
f"[speech][music_fmt]amix=inputs=2:duration=first:dropout_transition=2[aout]"
# normalize=0: amix's default normalize=1 divides every input by the
# input count (here x0.5 / -6 dB), which would permanently attenuate
# the narration across the whole timeline — including stretches where
# the music volume expression is 0. The music is already scaled by the
# `volume` expression, so speech must pass at unity. Unlike _mix/
# _full_mix, this path has no loudnorm stage to mask the halving.
f"[speech][music_fmt]amix=inputs=2:duration=first:dropout_transition=2:normalize=0[aout]"
)
cmd = [