import json import sys import os from pathlib import Path from dotenv import load_dotenv # Load environment variables from .env file load_dotenv() # Add project root to sys.path to allow importing backend modules project_root = Path(__file__).parent.parent sys.path.append(str(project_root)) from backend.audio_generator import generate_audio_for_script def rebuild_audio_from_props(): """ Reads assets/1_processed/render_props.json, generates new audio files for the narration text, and updates the durations and paths. """ 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 script from {props_path}...") with open(props_path, "r", encoding="utf-8") as f: props = json.load(f) # RE-INDEX segments first print("🔢 Re-indexing script segments and fixing paths...") for i, segment in enumerate(props["script"]): new_id = i + 1 segment["id"] = new_id # Determine if we should keep existing audio path current_path = segment.get("audioPath", "") is_original_clip = "dialogue_clip" in current_path if segment.get("visualType") == "video": if "audioPath" in segment: del segment["audioPath"] elif is_original_clip: # Keep the dialogue_clip path as is print(f" ⏭️ Segment {new_id}: Keeping original audio path {current_path}") pass else: # Assign standard naming for AI generated segments segment["audioPath"] = f"public/segment_{new_id:03d}.mp3" script_data = {"segments": props["script"]} # Generate new audio files (outputs to public/ folder) print("🎙️ Generating new audio files...") updated_script_data = generate_audio_for_script(script_data, voice="nova") # voice options: "alloy", "echo", "fable", "onyx", "nova", "shimmer" # Update the script in our props object props["script"] = updated_script_data["segments"] # Recalculate total duration if needed (Remotion uses segment durations) total_duration = sum(seg.get("duration", 0) for seg in props["script"]) print(f"⏱️ New total duration: {total_duration:.2f} seconds") # Save updated render_props.json with open(props_path, "w", encoding="utf-8") as f: json.dump(props, f, ensure_ascii=False, indent=2) print(f"✅ Successfully updated {props_path} with new audio and durations.") if __name__ == "__main__": rebuild_audio_from_props()