AI-video-lifeplan-demo/backend/update_broll.py

85 lines
2.7 KiB
Python
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import json
import os
import sys
from pathlib import Path
from dotenv import load_dotenv
# Add project root to sys.path
PROJECT_ROOT = Path(__file__).parent.parent
sys.path.append(str(PROJECT_ROOT))
from backend.media_fetcher import MediaFetcher
def update_broll_assets():
"""
Reads render_props.json, fetches B-Roll assets for segments that have
brollKeywords, and updates the assets.broll section.
Does NOT modify narration text.
"""
load_dotenv()
props_path = PROJECT_ROOT / "assets" / "1_processed" / "render_props.json"
if not props_path.exists():
print(f"❌ Error: {props_path} not found.")
return
print(f"📖 Reading {props_path}...")
with open(props_path, "r", encoding="utf-8") as f:
props = json.load(f)
# 1. Collect all keywords from script segments
keywords = set()
for segment in props.get("script", []):
kw = segment.get("brollKeyword")
if kw:
keywords.add(kw)
if not keywords:
print("ℹ️ No B-Roll keywords found in script. Skipping.")
return
print(f"🎬 Keywords found: {', '.join(keywords)}")
# 2. Fetch assets using MediaFetcher
try:
fetcher = MediaFetcher()
# Fetch 1 video per keyword
broll_results = fetcher.fetch_broll(list(keywords), max_per_keyword=1)
# 3. Update props["assets"]["broll"]
if "assets" not in props:
props["assets"] = {}
if "broll" not in props["assets"]:
props["assets"]["broll"] = {}
new_broll_map = {}
for kw, videos in broll_results.items():
if videos:
filename = Path(videos[0]["filepath"]).name
new_broll_map[kw] = filename
print(f" ✅ Mapped '{kw}' -> {filename}")
props["assets"]["broll"].update(new_broll_map)
# 4. Map brollPath in each segment for Remotion to use easily
# (Though Composition.tsx might already do this, we ensure consistency)
for segment in props.get("script", []):
kw = segment.get("brollKeyword")
if kw and kw in props["assets"]["broll"]:
filename = props["assets"]["broll"][kw]
segment["brollPath"] = f"broll/{filename}"
# 5. Save
with open(props_path, "w", encoding="utf-8") as f:
json.dump(props, f, ensure_ascii=False, indent=2)
print(f"✨ Successfully updated B-Roll assets in {props_path}")
except Exception as e:
print(f"❌ Failed to fetch B-Roll: {e}")
import traceback
traceback.print_exc()
if __name__ == "__main__":
update_broll_assets()