backup
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
"""
|
||||
Regenerate carpet extraction shots using Veo 3.1.
|
||||
Fixes: buffer/rotary/steamer machines replaced with explicit stand-up extractor descriptions.
|
||||
Reconcats hero-reel.mp4 when done.
|
||||
Run: python3 tools/regen-veo31.py
|
||||
"""
|
||||
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)
|
||||
|
||||
# Machine description block used across all shots
|
||||
MACHINE = (
|
||||
"The carpet cleaning machine looks exactly like a Rug Doctor or Bissell Big Green carpet cleaner — "
|
||||
"the large upright machines you rent at grocery stores. Tall rectangular body, upright handle, "
|
||||
"wide flat cleaning foot at the base. It is pushed forward in straight lines like a vacuum cleaner. "
|
||||
"NOT a floor buffer. NOT a rotary disc scrubber. NOT a steam cleaner. NOT circular. "
|
||||
"NO spinning parts. NO steam. NO water spraying out. The carpet is cleaned by suction alone."
|
||||
)
|
||||
|
||||
SHOTS = [
|
||||
{
|
||||
"name": "shot-04-extraction-carpet",
|
||||
"prompt": (
|
||||
f"Cinematic slow-motion wide shot. A man pushes a Rug Doctor style carpet cleaning machine "
|
||||
f"steadily forward across a beige residential carpet in a living room. {MACHINE} "
|
||||
f"The carpet behind the machine transitions from dirty and matted to bright, clean, and fluffy. "
|
||||
f"Warm natural room light. Photorealistic professional video."
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "shot-05-extraction-couch",
|
||||
"prompt": (
|
||||
"Close-up cinematic slow-motion shot. A professional technician's gloved hand holds a small "
|
||||
"flat handheld upholstery cleaning attachment — a rectangular suction wand, flat on the bottom, "
|
||||
"no moving parts, no spinning disc. "
|
||||
"The technician presses it firmly against a dirty grey sofa cushion and slides it slowly across. "
|
||||
"The fabric visibly brightens as the wand moves across it. "
|
||||
"NO rotary machine anywhere in frame. NO spinning. NO steam. NO water pouring out. "
|
||||
"Natural light. Photorealistic."
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "shot-06-extraction-stairs",
|
||||
"prompt": (
|
||||
"Cinematic slow-motion shot. A professional technician pushes a Rug Doctor style upright carpet "
|
||||
"cleaning machine up a carpeted residential staircase, one stair tread at a time. "
|
||||
"The machine is a tall rectangular upright unit with a handle and flat cleaning head — "
|
||||
"NOT a buffer, NOT circular, NOT rotating. "
|
||||
"Each stair tread brightens and looks freshly cleaned as the machine passes over it. "
|
||||
"NO steam, NO water visible. Warm interior light. Photorealistic."
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "shot-09-technician-unloading",
|
||||
"prompt": (
|
||||
f"Wide cinematic shot. A professional carpet cleaning technician in a plain black shirt "
|
||||
f"rolls a Rug Doctor style carpet cleaning machine down a ramp out of a white service van "
|
||||
f"parked in a residential driveway in upstate New York. {MACHINE} "
|
||||
f"Autumn trees in background, bright daylight. "
|
||||
f"Technician shown from the side or behind, no face visible. 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']} with {MODEL}...")
|
||||
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): {item['name']}")
|
||||
continue
|
||||
if op.response and op.response.generated_videos:
|
||||
vid = op.response.generated_videos[0].video
|
||||
# Veo 3.1 download pattern
|
||||
video_bytes = client.files.download(file=vid)
|
||||
if video_bytes:
|
||||
with open(out_path, "wb") as f:
|
||||
f.write(video_bytes)
|
||||
print(f" Saved {out_path} ({os.path.getsize(out_path)//1024}KB)")
|
||||
saved.append(item["name"])
|
||||
else:
|
||||
# fallback: try .save() method
|
||||
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 for {item['name']}")
|
||||
except Exception as e:
|
||||
print(f" Error: {e}")
|
||||
|
||||
print(f"\n{len(saved)}/{len(SHOTS)} shots saved: {saved}")
|
||||
|
||||
# Reconcat full reel
|
||||
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 clips: {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: {REEL_OUT} ({os.path.getsize(REEL_OUT)//1024}KB)")
|
||||
else:
|
||||
print(f" ffmpeg error: {result.stderr[-400:]}")
|
||||
|
||||
print("\nDone.")
|
||||
Reference in New Issue
Block a user