[object Object]

← back to Consulting Rentv Com

auto-save: 2026-07-23T13:51:43 (2 files) — data/audit-video/compose_noavatar.py data/audit-video/concat_clean.txt

9f15eaa72c639598d0d7bbd7d390a80a6157434a · 2026-07-23 13:51:44 -0700 · Steve Abrams

Files touched

Diff

commit 9f15eaa72c639598d0d7bbd7d390a80a6157434a
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Thu Jul 23 13:51:44 2026 -0700

    auto-save: 2026-07-23T13:51:43 (2 files) — data/audit-video/compose_noavatar.py data/audit-video/concat_clean.txt
---
 data/audit-video/compose_noavatar.py | 66 ++++++++++++++++++++++++++++++++++++
 data/audit-video/concat_clean.txt    |  3 ++
 2 files changed, 69 insertions(+)

diff --git a/data/audit-video/compose_noavatar.py b/data/audit-video/compose_noavatar.py
new file mode 100644
index 0000000..923f3d7
--- /dev/null
+++ b/data/audit-video/compose_noavatar.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+# Same as compose.py but WITHOUT the Steve avatar PIP. Keeps chips + title + outro.
+import json, subprocess, os
+from PIL import Image, ImageDraw, ImageFont
+HERE = os.path.dirname(os.path.abspath(__file__)); os.chdir(HERE)
+nar = json.load(open("narration.json")); tim = json.load(open("timing.json"))
+starts = tim["starts"]; audio_end = tim["audio_end"]; segs = nar["segments"]
+ids = [s["id"] for s in segs]
+ARIAL = "/System/Library/Fonts/Supplemental/Arial Bold.ttf"
+GOLD = (200,161,90); BG = (12,16,22); INK = (238,241,246)
+labels = {
+ "summary":"EXECUTIVE SUMMARY","swot":"SWOT ANALYSIS","reputation":"REPUTATION & AUTHORITY",
+ "empire":"THE EMPIRE & SUBLEASE.COM","competitors":"COMPETITORS","advertising":"WHERE TO ADVERTISE",
+ "timing":"TIMING & CADENCE","audit":"WEBSITE AUDIT","teardown":"PAGE-BY-PAGE TEARDOWN",
+ "social":"SOCIAL MEDIA AUDIT","suggested":"SUGGESTED NEW WEBSITES","partners":"UNLIKELY PARTNERS",
+ "revenue":"UNLIKELY REVENUE","videos":"VIDEO & BRAND FILMS","dealdesk":"LIVE DEAL DESK",
+ "roadmap":"90-DAY ROADMAP",
+}
+os.makedirs("chips", exist_ok=True)
+fnum = ImageFont.truetype(ARIAL, 30); ftxt = ImageFont.truetype(ARIAL, 30)
+padx, pady, gap = 26, 16, 16
+chip_paths = []
+tmp = ImageDraw.Draw(Image.new("RGBA",(10,10)))
+for i, id in enumerate(ids):
+    num = f"{i+1:02d}"; title = labels[id]
+    wn = tmp.textlength(num, font=fnum); wt = tmp.textlength(title, font=ftxt)
+    W = int(padx + wn + gap + wt + padx); H = 62
+    im = Image.new("RGBA", (W, H), (0,0,0,0)); d = ImageDraw.Draw(im)
+    d.rounded_rectangle([0,0,W-1,H-1], radius=8, fill=BG+(210,), outline=GOLD+(120,), width=1)
+    ty = (H-30)//2 - 4
+    d.text((padx, ty), num, font=fnum, fill=GOLD+(255,))
+    d.text((padx+wn+gap, ty), title, font=ftxt, fill=INK+(255,))
+    p = f"chips/{i:02d}.png"; im.save(p); chip_paths.append(p)
+print("chips:", len(chip_paths))
+
+# main body: NO avatar. input 1 kept only so 1:a preserves original length/parity.
+inputs = ["-i","rec/portal-walk.webm","-i","steve-narration.mp4"]
+for p in chip_paths: inputs += ["-i", p]
+fc = ["[0:v]scale=1920:1080,setsar=1,fps=25[bg]"]
+prev = "bg"
+for i, id in enumerate(ids):
+    s = 0.0 if i == 0 else starts[id]
+    e = starts[ids[i+1]] if i+1 < len(ids) else audio_end
+    inp = 2 + i
+    out = f"o{i}"
+    fc.append(f"[{prev}][{inp}:v]overlay=48:H-h-44:enable='between(t,{s:.2f},{e:.2f})'[{out}]")
+    prev = out
+fc_str = ";".join(fc)
+cmd = ["ffmpeg","-y",*inputs,"-filter_complex",fc_str,
+       "-map",f"[{prev}]","-map","1:a",
+       "-c:v","libx264","-pix_fmt","yuv420p","-crf","19","-preset","medium","-r","25",
+       "-c:a","aac","-b:a","160k","-ar","48000","-ac","2","-shortest","main_clean.mp4"]
+print("== main body (no avatar) =="); subprocess.run(cmd, check=True)
+
+def card(png, out, dur):
+    subprocess.run(["ffmpeg","-y","-loop","1","-i",png,"-f","lavfi","-i","anullsrc=r=48000:cl=stereo",
+        "-t",str(dur),"-vf",f"scale=1920:1080,fps=25,fade=in:0:15,fade=out:st={dur-0.6:.2f}:d=0.6",
+        "-c:v","libx264","-pix_fmt","yuv420p","-r","25","-c:a","aac","-b:a","160k","-shortest",out], check=True)
+print("== title / outro =="); card("title.png","title.mp4",4.0); card("outro.png","outro.mp4",4.0)
+
+open("concat_clean.txt","w").write("file 'title.mp4'\nfile 'main_clean.mp4'\nfile 'outro.mp4'\n")
+r = subprocess.run(["ffmpeg","-y","-f","concat","-safe","0","-i","concat_clean.txt","-c","copy","clean_final.mp4"])
+if r.returncode != 0:
+    subprocess.run(["ffmpeg","-y","-f","concat","-safe","0","-i","concat_clean.txt",
+        "-c:v","libx264","-pix_fmt","yuv420p","-crf","19","-r","25","-c:a","aac","-b:a","160k","clean_final.mp4"], check=True)
+print("DONE -> clean_final.mp4")
diff --git a/data/audit-video/concat_clean.txt b/data/audit-video/concat_clean.txt
new file mode 100644
index 0000000..4663389
--- /dev/null
+++ b/data/audit-video/concat_clean.txt
@@ -0,0 +1,3 @@
+file 'title.mp4'
+file 'main_clean.mp4'
+file 'outro.mp4'

← d203297 auto-save: 2026-07-23T13:21:35 (1 files) — data/intakes.json  ·  back to Consulting Rentv Com  ·  portal: drop the outbound rentv.com link (plain text, no lin 4ff250a →