Files
lahrcarpetcleaning.com/tools/regen-3shots.py
T
Concept Agent 307e452251 backup
2026-05-15 18:02:38 +02:00

143 lines
5.2 KiB
Python

"""
Regen shot-04, shot-06, shot-07 with corrected scenes.
shot-04: carpet before/after reveal, no machine
shot-06: clean bright staircase, no machine
shot-07: bright modern office, no dark tones
"""
import os, sys, time, subprocess
try:
from google import genai
from google.genai import types
except ImportError:
os.system(f"{sys.executable} -m pip install google-genai --quiet")
from google import genai
from google.genai import types
API_KEY = os.environ.get("GEMINI_API_KEY", "AIzaSyB_1p8KvaT_rdNJGPs8HKk8bKsvUlcL6Kg")
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
VID_DIR = os.path.join(BASE_DIR, "assets", "videos", "hero", "clips")
REEL_OUT = os.path.join(BASE_DIR, "assets", "videos", "hero", "hero-reel.mp4")
client = genai.Client(api_key=API_KEY)
SHOTS = [
{
"name": "shot-04-extraction-carpet",
"prompt": (
"Cinematic slow-motion wide shot. Camera glides low across a residential living room carpet. "
"The left half of the carpet is visibly dirty, stained, and matted. "
"The right half is bright, clean, fluffy, and freshly extracted. "
"The boundary between dirty and clean is sharp and dramatic. "
"Warm natural afternoon light. No people. No machines. No equipment. Photorealistic."
),
},
{
"name": "shot-06-extraction-stairs",
"prompt": (
"Cinematic slow-motion shot looking up a bright residential carpeted staircase. "
"Each step has clean, bright, plush beige carpet with fresh extraction lines. "
"Warm natural light from above illuminates the stairs. Wood banisters on each side. "
"No people. No machines. No equipment anywhere in frame. Photorealistic."
),
},
{
"name": "shot-07-office-entryway",
"prompt": (
"Wide cinematic shot of a bright modern commercial office building lobby. "
"Large windows let in abundant natural daylight. Clean beige or grey commercial carpet throughout. "
"White walls, professional lighting, glass doors, contemporary furniture. "
"The carpet looks spotlessly clean with neat vacuum lines. "
"No people. No machines. No dark tones — the space is bright and well-lit. Photorealistic."
),
},
]
MODEL = "veo-3.1-generate-preview"
def poll(op, timeout=600):
elapsed = 0
while not op.done:
if elapsed >= timeout:
print(f" Timed out after {timeout}s.")
return None
print(f" Waiting... ({elapsed}s)")
time.sleep(15)
elapsed += 15
op = client.operations.get(op)
return op
saved = []
for item in SHOTS:
out_path = os.path.join(VID_DIR, f"{item['name']}.mp4")
print(f"\n[VID] Generating {item['name']}...")
try:
op = client.models.generate_videos(
model=MODEL,
prompt=item["prompt"],
config=types.GenerateVideosConfig(
aspect_ratio="16:9",
resolution="720p",
duration_seconds=6,
number_of_videos=1,
),
)
op = poll(op)
if op is None:
print(f" FAILED (timeout)")
continue
if op.response and op.response.generated_videos:
vid = op.response.generated_videos[0].video
video_bytes = client.files.download(file=vid)
if video_bytes:
with open(out_path, "wb") as f:
f.write(video_bytes)
print(f" Saved ({os.path.getsize(out_path)//1024}KB)")
saved.append(item["name"])
else:
try:
vid.save(out_path)
print(f" Saved via .save() ({os.path.getsize(out_path)//1024}KB)")
saved.append(item["name"])
except Exception as e2:
print(f" Download failed: {e2}")
else:
print(f" No video returned")
except Exception as e:
print(f" Error: {e}")
print(f"\n{len(saved)}/{len(SHOTS)} shots saved: {saved}")
ORDER = [
"shot-01-door-opens-trimmed",
"shot-02-pan-to-stains",
"shot-03-stain-closeup",
"shot-04-extraction-carpet",
"shot-05-extraction-couch",
"shot-06-extraction-stairs",
"shot-07-office-entryway",
"shot-08-showroom",
"shot-09-technician-unloading",
]
missing = [n for n in ORDER if not os.path.exists(os.path.join(VID_DIR, f"{n}.mp4"))]
if missing:
print(f"\nSkipping reconcat — missing: {missing}")
else:
print("\nReconcatenating hero-reel.mp4...")
concat_file = os.path.join(VID_DIR, "concat.txt")
with open(concat_file, "w") as f:
for name in ORDER:
f.write(f"file '{os.path.join(VID_DIR, name)}.mp4'\n")
result = subprocess.run(
["ffmpeg", "-y", "-f", "concat", "-safe", "0", "-i", concat_file,
"-c:v", "libx264", "-crf", "22", "-preset", "fast",
"-movflags", "+faststart", REEL_OUT],
capture_output=True, text=True
)
if result.returncode == 0:
print(f" Reel saved ({os.path.getsize(REEL_OUT)//1024}KB)")
else:
print(f" ffmpeg error: {result.stderr[-400:]}")
print("\nDone.")