Removing infinite buffering length for a background video

This commit is contained in:
2026-07-25 14:09:17 +02:00
parent b60be96978
commit a84e02b494
3 changed files with 19 additions and 5 deletions
+4 -1
View File
@@ -2802,7 +2802,10 @@ def cmd_preprocess(
entry = dict(existing_narration.get(segment_id, {}))
# Always record the plain path; the res subdir shift happens at render for low/tiny.
entry["processed_file"] = f"processed/{segment_id}_processed.mov"
entry.setdefault("use_audio_channels", "auto")
# Store the RESOLVED audio channel (preprocess_video mutated "auto" → the
# detected left/right/both). This is the concrete value; render reads it and
# never re-runs the auto-detect probe.
entry["use_audio_channels"] = segment_source.use_audio_channels or "auto"
entry.setdefault("defer_loudnorm", False)
existing_narration[segment_id] = entry
+4
View File
@@ -715,6 +715,10 @@ def preprocess_video(
if channel == "auto":
channel = _resolve_auto_channel(current_input)
print(f" Auto channel detection: using '{channel}'")
# Persist the resolved channel on the source so the caller can store it back
# to narration.json — the auto-detect (a full-file volumedetect) then runs
# ONCE here at preprocess, never again at render time.
video_source.use_audio_channels = channel
elif channel in ("left", "right"):
is_silent, max_vol = check_audio_channel_silent(current_input, channel)
if is_silent:
+11 -4
View File
@@ -319,12 +319,15 @@ def _build_audio_channel_filter(use_audio_channels: str) -> str:
use_audio_channels: "both", "left", or "right"
Returns:
Filter string (e.g., "pan=mono|c0=c1") or empty string for "both"
Filter string, or empty string for "both".
Matches preprocess (apply_audio_normalize): a selected single channel is
duplicated to BOTH output channels (centered stereo), not collapsed to mono.
"""
if use_audio_channels == "left":
return "pan=mono|c0=c0"
return "pan=stereo|c0=c0|c1=c0"
elif use_audio_channels == "right":
return "pan=mono|c0=c1"
return "pan=stereo|c0=c1|c1=c1"
return "" # "both" - no filter needed
@@ -458,9 +461,13 @@ def build_ffmpeg_command(plan: RenderPlan, output_path: Path) -> list[str]:
)
image_extensions = {".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".webp"}
bg_is_image = bg_path.suffix.lower() in image_extensions
# Loop background videos infinitely
# Loop background videos, but BOUND the loop to the output length. An
# unbounded -stream_loop -1 input can make ffmpeg read/buffer ahead without
# limit, which balloons memory on long renders — cap it with an input -t so
# it EOFs cleanly at total_duration.
if not bg_is_image:
cmd.extend(["-stream_loop", "-1"])
cmd.extend(["-t", f"{plan.total_duration:.3f}"])
# Duration of background video is irrelevant (looped or image) — skip analysis
cmd.extend(["-analyzeduration", "0", "-probesize", "1000"])
cmd.extend(["-i", str(bg_path)])