feat(pipeline): frame stage ffmpeg arg builder (content pipeline §3.2)

This commit is contained in:
BenStullsBets
2026-06-24 07:53:28 -07:00
parent 750e87eb0b
commit 642451925f
3 changed files with 52 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
"""Content pipeline: source -> frame -> loop -> transcode -> manifest.
Pure ffmpeg-argument builders (ffmpeg_ops), a thin runner (run), provenance
records, and manifest assembly. See docs/superpowers/specs/2026-06-24-content-pipeline-design.md.
"""
+30
View File
@@ -0,0 +1,30 @@
"""Pure ffmpeg argument builders (no I/O) for the content pipeline.
Each function returns a list[str] ready for ffmpeg, so command construction is
unit-testable without running ffmpeg. tools/pipeline/run.py executes them. The
ffmpeg binary name is injected (default "ffmpeg").
"""
from __future__ import annotations
def _fit(width: int, height: int) -> str:
"""A scale+pad filter chain fitting any input into width×height (letterbox),
fixing SAR and pixel format so downstream concat/xfade get identical geometry."""
return (
f"scale={width}:{height}:force_original_aspect_ratio=decrease,"
f"pad={width}:{height}:(ow-iw)/2:(oh-ih)/2,"
"setsar=1,format=yuv420p"
)
def frame_args(src, dst, *, start: float, duration: float,
width: int, height: int, ff: str = "ffmpeg") -> list[str]:
"""Stage 2 — trim [start, start+duration], fit to width×height, strip audio.
Produces a high-quality mezzanine for the loop stage."""
return [
ff, "-y", "-ss", str(start), "-t", str(duration),
"-i", str(src), "-vf", _fit(width, height), "-an",
"-c:v", "libx264", "-preset", "medium", "-crf", "16",
"-pix_fmt", "yuv420p", "-movflags", "+faststart", str(dst),
]