File size: 1,282 Bytes
9459cd0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
"""
Audio Engine — voice always wins. BGM auto-ducks under voice via sidechain
compression; everything gets loudness-normalized before mixdown.
"""


def build_audio_filter(has_voice: bool, has_bgm: bool, bgm_volume: float = 0.15) -> dict:
    """
    Returns {"extra_inputs": [...], "filter_lines": [...], "audio_out_label": str|None}
    Caller is responsible for appending voice/bgm as -i inputs in the same
    order this expects (voice first if present, then bgm).
    """
    lines = []
    label = None

    if has_voice and has_bgm:
        lines.append("[voice]loudnorm=I=-16:TP=-1.5:LRA=11[voice_n]")
        lines.append(f"[bgm]volume={bgm_volume}[bgm_v]")
        # sidechain: bgm ducks whenever voice is present
        lines.append(
            "[bgm_v][voice_n]sidechaincompress=threshold=0.05:ratio=8:attack=5:release=300[bgm_duck]"
        )
        lines.append("[voice_n][bgm_duck]amix=inputs=2:duration=first:dropout_transition=2[aout]")
        label = "aout"
    elif has_voice:
        lines.append("[voice]loudnorm=I=-16:TP=-1.5:LRA=11[aout]")
        label = "aout"
    elif has_bgm:
        lines.append(f"[bgm]volume={bgm_volume},loudnorm=I=-18:TP=-1.5:LRA=11[aout]")
        label = "aout"

    return {"filter_lines": lines, "audio_out_label": label}