Files
human-experience-filter-art/tools/pipeline/run.py
T
2026-06-24 08:01:25 -07:00

50 lines
1.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Thin runner: ffprobe the source, then execute the frame -> loop -> transcode
stages with tools.pipeline.ffmpeg_ops. The pure arg builders are unit-tested;
this glue is covered by the opt-in integration test."""
from __future__ import annotations
import subprocess
from pathlib import Path
from .ffmpeg_ops import crossfade_loop_args, frame_args, transcode_args
MASTER_MAX_W = 3840
def probe_duration(src, *, ff: str = "ffprobe") -> float:
out = subprocess.run(
[ff, "-v", "quiet", "-show_entries", "format=duration",
"-of", "csv=p=0", str(src)],
capture_output=True, text=True, check=True,
).stdout.strip()
return float(out)
def _run(args: list[str]) -> None:
subprocess.run(args, check=True, capture_output=True)
def process_clip(src, out_dir, *, start: float = 0.0, duration: float | None = None,
overlap: float = 1.0, master_w: int = 3840, master_h: int = 2160,
ff: str = "ffmpeg") -> dict:
"""Run stages 24 for one clip; return {'master','proxy','loop','mezzanine'} paths.
`duration` defaults to the full source length (minus the trim start)."""
src = Path(src)
out_dir = Path(out_dir)
out_dir.mkdir(parents=True, exist_ok=True)
if duration is None:
duration = probe_duration(src) - start
mezz = out_dir / "mezzanine.mp4"
loop = out_dir / "loop.mp4"
master = out_dir / "master.mp4"
proxy = out_dir / "base.mp4" # the proxy is what the manifest's base_file points at
_run(frame_args(src, mezz, start=start, duration=duration,
width=master_w, height=master_h, ff=ff))
_run(crossfade_loop_args(mezz, loop, duration=duration, overlap=overlap, ff=ff))
_run(transcode_args(loop, master, width=master_w, height=master_h, crf=18, ff=ff))
_run(transcode_args(loop, proxy, width=1920, height=1080, crf=20, ff=ff))
return {"mezzanine": mezz, "loop": loop, "master": master, "proxy": proxy}