Duck soundtrack when using clip audio

This commit is contained in:
hbrain 2026-05-28 16:39:02 +00:00
parent 2ca263dd58
commit af3fd51226
2 changed files with 44 additions and 8 deletions

View file

@ -50,6 +50,11 @@ DEFAULT_AUDIO_FADE_IN = 2.0
DEFAULT_AUDIO_FADE_OUT = 10.0
DEFAULT_VIDEO_FADE = 1.0
INTRO_VIDEO_FADE_ENABLED = False
CLIP_AUDIO_FADE = 0.75
CLIP_AUDIO_SIDECHAIN_THRESHOLD = 0.04
CLIP_AUDIO_SIDECHAIN_RATIO = 8.0
CLIP_AUDIO_SIDECHAIN_ATTACK = 5.0
CLIP_AUDIO_SIDECHAIN_RELEASE = 250.0
JAMENDO_ENV = Path.home() / ".config" / "movmaker" / "jamendo.env"
LOG_PATH: Path | None = None
@ -1109,7 +1114,7 @@ def build_video(
f"fontsize={stamp_size}:fontcolor=white:borderw=1:bordercolor=black[{final_label}]"
)
audio_mix_labels: list[str] = []
bg_audio_label: str | None = None
if audio:
audio_index = len(clips)
audio_fade_out_start = max(0.0, total_duration - audio_fade)
@ -1117,7 +1122,8 @@ def build_video(
f"[{audio_index}:a:0]atrim=0:{total_duration:.3f},asetpts=PTS-STARTPTS,"
f"afade=t=in:st=0:d={audio_fade_in:.3f},afade=t=out:st={audio_fade_out_start:.3f}:d={audio_fade:.3f}[bg_audio]"
)
audio_mix_labels.append("[bg_audio]")
bg_audio_label = "bg_audio"
clip_audio_labels: list[str] = []
clip_audio_input = clip_audio_input_start
for idx, clip_audio in enumerate(clip_audio_paths):
if clip_audio is None:
@ -1138,7 +1144,7 @@ def build_video(
if segment <= 0:
clip_audio_input += 1
continue
fade_len = min(fade, segment / 2)
fade_len = min(CLIP_AUDIO_FADE, segment / 2)
delay_ms = max(0, int(start * 1000))
label = f"clip_audio_{idx}"
filters.append(
@ -1146,10 +1152,38 @@ def build_video(
f"afade=t=in:st=0:d={fade_len:.3f},afade=t=out:st={max(0.0, segment - fade_len):.3f}:d={fade_len:.3f},"
f"adelay={delay_ms}:all=1[{label}]"
)
audio_mix_labels.append(f"[{label}]")
clip_audio_labels.append(label)
clip_audio_input += 1
if audio_mix_labels:
filters.append("".join(audio_mix_labels) + f"amix=inputs={len(audio_mix_labels)}:duration=longest:normalize=0[aout]")
clip_mix_label: str | None = None
if clip_audio_labels:
if len(clip_audio_labels) == 1:
clip_mix_label = clip_audio_labels[0]
else:
inputs = "".join(f"[{name}]" for name in clip_audio_labels)
filters.append(inputs + f"amix=inputs={len(clip_audio_labels)}:duration=longest:normalize=0[clip_mix]")
clip_mix_label = "clip_mix"
final_bg_label = bg_audio_label
final_clip_label = clip_mix_label
if final_bg_label and final_clip_label:
sc_label = f"{final_clip_label}_sc"
mix_label = f"{final_clip_label}_main"
filters.append(f"[{final_clip_label}]asplit=2[{sc_label}][{mix_label}]")
filters.append(
f"[{final_bg_label}][{sc_label}]sidechaincompress=threshold={CLIP_AUDIO_SIDECHAIN_THRESHOLD}:"
f"ratio={CLIP_AUDIO_SIDECHAIN_RATIO}:attack={CLIP_AUDIO_SIDECHAIN_ATTACK}:"
f"release={CLIP_AUDIO_SIDECHAIN_RELEASE}[bg_ducked]"
)
final_bg_label = "bg_ducked"
final_clip_label = mix_label
if final_bg_label and final_clip_label:
filters.append(f"[{final_bg_label}][{final_clip_label}]amix=inputs=2:duration=longest:normalize=0[aout]")
elif final_bg_label:
filters.append(f"[{final_bg_label}]anull[aout]")
elif final_clip_label:
filters.append(f"[{final_clip_label}]anull[aout]")
cmd += ["-filter_complex", ";".join(filters), "-map", f"[{final_label}]"]
metadata = {
@ -1168,7 +1202,7 @@ def build_video(
if value:
cmd += ["-metadata", f"{key}={value}"]
if audio_mix_labels:
if final_bg_label or final_clip_label:
cmd += ["-map", "[aout]", "-c:a", "aac", "-b:a", "192k", "-shortest"]
else:
cmd += ["-an"]