"""Replace v3-shot-04 with a clean sofa result — no cleaning action, no equipment, no steam.""" 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) PROMPTS = [ ( "Close-up cinematic shot slowly pulling back from a clean, bright grey upholstered sofa cushion. " "The fabric is fresh, fluffy, and spotless. Warm natural window light. " "No people. No machines. No equipment of any kind. No steam. No water. " "Just a beautiful clean sofa in a bright living room. Photorealistic." ), ( "Slow cinematic pan across a clean living room. A light grey sofa with pristine cushions. " "Bright clean beige carpet on the floor. Warm afternoon light. " "No people. No machines. No equipment. Photorealistic." ), ] MODEL = "veo-3.1-generate-preview" out_path = os.path.join(VID_DIR, "v3-shot-04.mp4") def poll(op, timeout=600): elapsed = 0 while not op.done: if elapsed >= timeout: return None print(f" Waiting... ({elapsed}s)") time.sleep(15) elapsed += 15 op = client.operations.get(op) return op saved = False for i, prompt in enumerate(PROMPTS): print(f"\n[v3-shot-04] attempt {i+1}...") try: op = client.models.generate_videos( model=MODEL, prompt=prompt, config=types.GenerateVideosConfig( aspect_ratio="16:9", resolution="720p", duration_seconds=6, number_of_videos=1, ), ) op = poll(op) if op and 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 = True break else: print(f" No video returned") except Exception as e: print(f" Error: {e}") if saved: clips = [ "v3-shot-01", "v3-shot-02", "v3-shot-03", "v3-shot-04", "v3-shot-05", "v3-shot-06", "v3-shot-07", ] missing = [n for n in clips if not os.path.exists(os.path.join(VID_DIR, f"{n}.mp4"))] if missing: print(f"Skipping reconcat — missing: {missing}") else: concat_file = os.path.join(VID_DIR, "concat-v3.txt") with open(concat_file, "w") as f: for n in clips: f.write(f"file '{os.path.join(VID_DIR, n)}.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[-300:]}") else: print("Failed — shot-04 unchanged.") print("\nDone.")