help quicky produce instagram reels and youtube shorts
80
93%
Does it follow best practices?
Impact
47%
1.95xAverage score across 1 eval scenario
Passed
No known issues
#!/usr/bin/env python3
"""QC a rendered reel before showing it to the human.
Checks every cut boundary in the plan:
- black/near-black frames at a cut (bad trim or empty source region)
- frozen cut (frame before == frame after -> the "cut" is invisible,
usually two segments from the same clip region)
- duration drift between plan and rendered file
Produces:
- contact sheet PNG: frame pairs (last frame of seg N | first of seg N+1)
for visual inspection by the agent BEFORE the human sees the preview
- report JSON with per-cut verdicts
Usage: check_cuts.py plan/cut_plan.json preview/draft_v1.mp4 \
--out work/qc_v1 (writes qc_v1.png + qc_v1.json)
"""
import argparse, json, subprocess, sys
from pathlib import Path
def run(cmd):
r = subprocess.run(cmd, capture_output=True, text=True)
if r.returncode != 0:
sys.exit(f"ffmpeg failed:\n{r.stderr[-600:]}")
return r
def frame_stats(video, t, out_png):
"""Grab frame at t; return (mean_luma, saved_path)."""
run(["ffmpeg", "-y", "-v", "error", "-ss", f"{max(0, t):.3f}", "-i", str(video),
"-frames:v", "1", "-vf", "scale=270:480", str(out_png)])
r = subprocess.run(
["ffmpeg", "-i", str(out_png), "-vf", "signalstats,metadata=print",
"-f", "null", "-"], capture_output=True, text=True)
mean = None
for line in r.stderr.splitlines():
if "YAVG" in line:
mean = float(line.split("=")[-1])
return mean if mean is not None else -1
def main():
ap = argparse.ArgumentParser()
ap.add_argument("plan")
ap.add_argument("video")
ap.add_argument("--out", default="work/qc")
ap.add_argument("--black-thresh", type=float, default=16.0,
help="mean luma below this = black frame")
args = ap.parse_args()
plan = json.loads(Path(args.plan).read_text())
outbase = Path(args.out)
outbase.parent.mkdir(parents=True, exist_ok=True)
tmp = outbase.parent / "_qc_frames"
tmp.mkdir(exist_ok=True)
# rendered duration vs plan
r = subprocess.run(["ffprobe", "-v", "quiet", "-show_entries", "format=duration",
"-of", "csv=p=0", args.video], capture_output=True, text=True)
rendered = float(r.stdout.strip())
drift = rendered - plan["total_duration"]
# cut times = cumulative segment durations
cuts, t = [], 0.0
for seg in plan["segments"][:-1]:
t += seg["duration"]
cuts.append(round(t, 3))
issues, pairs = [], []
eps = 1 / 30 / 2 # half a frame
for i, ct in enumerate(cuts):
before = tmp / f"cut{i:02d}_before.png"
after = tmp / f"cut{i:02d}_after.png"
luma_b = frame_stats(args.video, ct - eps - 1/30, before)
luma_a = frame_stats(args.video, ct + eps, after)
verdict = "ok"
if luma_b < args.black_thresh or luma_a < args.black_thresh:
verdict = "BLACK_FRAME"
pairs.append((before, after))
# frozen-cut check: pixel difference between the two frames
d = subprocess.run(
["ffmpeg", "-i", str(before), "-i", str(after),
"-lavfi", "psnr", "-f", "null", "-"],
capture_output=True, text=True)
psnr = None
for line in d.stderr.splitlines():
if "average:" in line:
try:
psnr = float(line.split("average:")[1].split()[0])
except ValueError:
psnr = 99.0 # 'inf' -> identical
if psnr is None or psnr > 45:
verdict = "FROZEN_CUT" if verdict == "ok" else verdict + "+FROZEN"
issues.append({"cut": i, "time": ct, "luma_before": round(luma_b, 1),
"luma_after": round(luma_a, 1),
"psnr_across_cut": psnr, "verdict": verdict})
# contact sheet: stack all pairs into a grid (2 cols per cut)
inputs, filters = [], []
for i, (b, a) in enumerate(pairs):
inputs += ["-i", str(b), "-i", str(a)]
filters.append(f"[{2*i}][{2*i+1}]hstack[row{i}]")
if pairs:
graph = ";".join(filters)
if len(pairs) > 1:
graph += ";" + "".join(f"[row{i}]" for i in range(len(pairs))) + \
f"vstack=inputs={len(pairs)}[sheet]"
outmap = "[sheet]"
else:
outmap = "[row0]"
run(["ffmpeg", "-y", "-v", "error"] + inputs +
["-filter_complex", graph, "-map", outmap,
"-frames:v", "1", f"{outbase}.png"])
report = {"video": args.video, "planned_duration": plan["total_duration"],
"rendered_duration": round(rendered, 2), "drift_s": round(drift, 2),
"cuts": issues,
"problems": [c for c in issues if c["verdict"] != "ok"]}
Path(f"{outbase}.json").write_text(json.dumps(report, indent=2))
n_bad = len(report["problems"])
print(f"QC: {len(cuts)} cuts checked, {n_bad} problem(s), "
f"duration drift {drift:+.2f}s")
for c in report["problems"]:
print(f" cut {c['cut']} @ {c['time']}s: {c['verdict']}")
print(f"Contact sheet: {outbase}.png Report: {outbase}.json")
if abs(drift) > 0.5:
print(f"WARNING: rendered duration off by {drift:+.2f}s vs plan")
if __name__ == "__main__":
main()