mirror of
https://github.com/zhouxiaoka/autoclip.git
synced 2026-10-02 02:34:34 +08:00
fix(render): dim and cheaply blur the vertical backdrop
The blurred backdrop behind fitted landscape footage enlarged burned captions into a readable ghost line. Blur at 1/8 size (harder blur, far less CPU than a full-resolution gblur) and dim it to about 35% so source text no longer reads in the backdrop. Shared by legacy export and speaker framing. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -138,13 +138,24 @@ def _load_srt_entries(project_id: str) -> List[Dict[str, Any]]:
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- ffmpeg ---
|
||||
def blurred_backdrop(w: int, h: int) -> str:
|
||||
"""Filter chain (no labels) turning the source into a dim, heavily blurred full-canvas backdrop.
|
||||
|
||||
Blurring at 1/8 size is far cheaper than a full-resolution gblur and blurs harder; dimming to
|
||||
~35% keeps text in the source (burned captions, lower thirds) from reading as a ghost copy.
|
||||
"""
|
||||
sw, sh = max(2, w // 8 // 2 * 2), max(2, h // 8 // 2 * 2)
|
||||
return (f"scale={sw}:{sh}:force_original_aspect_ratio=increase,crop={sw}:{sh},gblur=sigma=6,"
|
||||
f"colorlevels=romax=0.35:gomax=0.35:bomax=0.35,scale={w}:{h}")
|
||||
|
||||
|
||||
def _layout_filters(layout: str, w: Optional[int], h: Optional[int]) -> List[str]:
|
||||
if layout == "none" or not w or not h:
|
||||
return []
|
||||
if layout == "blur":
|
||||
return [
|
||||
f"[0:v]split=2[bg][fg]",
|
||||
f"[bg]scale={w}:{h}:force_original_aspect_ratio=increase,crop={w}:{h},gblur=sigma=24[bg2]",
|
||||
f"[bg]{blurred_backdrop(w, h)}[bg2]",
|
||||
f"[fg]scale={w}:-2[fg2]",
|
||||
f"[bg2][fg2]overlay=(W-w)/2:(H-h)/2[base]",
|
||||
]
|
||||
|
||||
@@ -185,8 +185,9 @@ def fit_spans(scene: Scene) -> list[tuple[float, float]]:
|
||||
return spans
|
||||
|
||||
|
||||
def layout_filter(scene: Scene, fallback: float, w: int, h: int, blur: int = 24) -> str:
|
||||
def layout_filter(scene: Scene, fallback: float, w: int, h: int) -> str:
|
||||
"""The `[0:v]…[base]` chain for a cropped scene, switching to a blurred fit on `fit` shots."""
|
||||
from backend.services.publish_export import blurred_backdrop
|
||||
cropped = (f"scale={w}:{h}:force_original_aspect_ratio=increase,"
|
||||
f"crop={w}:{h}:x='(iw-ow)*{crop_expression(scene, fallback)}':y=(ih-oh)/2,setsar=1")
|
||||
spans = fit_spans(scene)
|
||||
@@ -194,7 +195,7 @@ def layout_filter(scene: Scene, fallback: float, w: int, h: int, blur: int = 24)
|
||||
return f"[0:v]{cropped}[base]"
|
||||
enable = "+".join(f"between(t,{start},{end})" for start, end in spans)
|
||||
return (f"[0:v]split=3[c][bg][fg];[c]{cropped}[cropped];"
|
||||
f"[bg]scale={w}:{h}:force_original_aspect_ratio=increase,crop={w}:{h},gblur=sigma={blur}[bg2];"
|
||||
f"[bg]{blurred_backdrop(w, h)}[bg2];"
|
||||
f"[fg]scale={w}:{h}:force_original_aspect_ratio=decrease[fg2];"
|
||||
f"[bg2][fg2]overlay=(W-w)/2:(H-h)/2[fitted];"
|
||||
f"[cropped][fitted]overlay=0:0:enable='{enable}'[base]")
|
||||
|
||||
Reference in New Issue
Block a user