mirror of
https://github.com/calesthio/OpenMontage.git
synced 2026-08-24 17:10:27 +08:00
fix(green_screen): make chromakey compositing portable across FFmpeg builds
The CI Linux FFmpeg build carried the keyed frame forward without an alpha plane, so overlay drew opaque green over the background (corner stayed green) instead of compositing — the E2E test failed there even though it passed on macOS/Windows. Force `format=yuva420p` immediately after chromakey so the keyed transparency always has an explicit alpha plane, and size the background to the frame up front (color=...:size=WxH, passing the probed width/height into _process_chromakey) instead of scaling a 1x1 source with scale2ref — dropping scale2ref also removes the format negotiation that discarded the alpha on some builds. Output is flattened to yuv420p after the overlay.
This commit is contained in:
@@ -161,7 +161,7 @@ class GreenScreenProcessor(BaseTool):
|
||||
|
||||
if method == "chromakey":
|
||||
ok = self._process_chromakey(
|
||||
frames_dir, processed_dir, bg_color, frame_count
|
||||
frames_dir, processed_dir, bg_color, frame_count, width, height
|
||||
)
|
||||
else:
|
||||
ok = self._process_rembg(
|
||||
@@ -445,6 +445,8 @@ class GreenScreenProcessor(BaseTool):
|
||||
processed_dir: Path,
|
||||
bg_color: str,
|
||||
frame_count: int,
|
||||
width: int,
|
||||
height: int,
|
||||
) -> bool:
|
||||
"""Process frames using FFmpeg chromakey filter.
|
||||
|
||||
@@ -461,20 +463,23 @@ class GreenScreenProcessor(BaseTool):
|
||||
out_path = processed_dir / frame.name
|
||||
cmd = [
|
||||
"ffmpeg", "-y",
|
||||
"-f", "lavfi", "-i", f"color=c={ffmpeg_bg}:size=1x1",
|
||||
# Background sized to the frame up front. The old code used a 1x1
|
||||
# color source and `[0:v]scale=iw:ih` — a no-op (iw/ih were the
|
||||
# 1x1 source's own size) — and overlay takes the size of its
|
||||
# FIRST input, so every frame was clipped to a single pixel and
|
||||
# the whole video came out a solid color with the subject gone.
|
||||
"-f", "lavfi", "-i", f"color=c={ffmpeg_bg}:size={width}x{height}",
|
||||
"-i", str(frame),
|
||||
"-filter_complex",
|
||||
(
|
||||
# The background is a 1x1 color source; it MUST be scaled up
|
||||
# to the frame's dimensions. `scale=iw:ih` on [0:v] alone is a
|
||||
# no-op (iw/ih are the 1x1 source's own size), and overlay
|
||||
# takes the size of its FIRST input — so that leaves a 1x1
|
||||
# canvas and the keyed frame gets clipped to a single pixel,
|
||||
# producing a solid-color video with the subject gone.
|
||||
# scale2ref resizes [0:v] to match the frame [1:v] first.
|
||||
f"[1:v]chromakey=color=0x00FF00:similarity=0.3:blend=0.08[fg];"
|
||||
f"[0:v][fg]scale2ref[bg][fg2];"
|
||||
f"[bg][fg2]overlay=0:0"
|
||||
# Force an explicit alpha format after chromakey so the keyed
|
||||
# transparency survives filter negotiation on every FFmpeg
|
||||
# build — without it, some Linux builds carry the keyed frame
|
||||
# forward without an alpha plane and overlay draws opaque
|
||||
# green over the background instead of compositing.
|
||||
f"[1:v]chromakey=color=0x00FF00:similarity=0.3:blend=0.08,"
|
||||
f"format=yuva420p[fg];"
|
||||
f"[0:v][fg]overlay=0:0:format=auto,format=yuv420p"
|
||||
),
|
||||
"-frames:v", "1",
|
||||
str(out_path),
|
||||
|
||||
Reference in New Issue
Block a user