"""Generate a representative sample broadcast video demonstrating the complete LeagueForge pipeline.""" from __future__ import annotations import time from pathlib import Path from rich.console import Console from leagueforge.edl.builder import build_episode_edl from leagueforge.league.tournament import TournamentManager from leagueforge.map.builder import build_landscape_round_track from leagueforge.meta.chapters import format_youtube_description, generate_episode_chapters from leagueforge.meta.thumbnail import generate_thumbnail from leagueforge.render.renderer import render_episode_mp4 console = Console() def main() -> None: out_dir = Path("out/sample_episode") out_dir.mkdir(parents=True, exist_ok=True) out_mp4 = Path("out/league_episode_sample.mp4") seed = 8080 console.print(f"[bold cyan]1. Simulating 15-Round Tournament for Seed #{seed}...[/bold cyan]") t0 = time.perf_counter() tm = TournamentManager(out_dir=out_dir) episode_tl, commit_rec = tm.run_episode(seed, target_round_s=15.0, fps_sim=120) sim_time = time.perf_counter() - t0 console.print(f"[green]✓[/green] Simulation finished in {sim_time:.2f}s!") champ = tm.get_racer_for_slot(commit_rec, episode_tl.champion_slot) console.print(f" Champion: [bold]{champ.numeral} {champ.name}[/bold] ({champ.hex_color})") console.print(f" Commit Hash: {episode_tl.commit_sha256}") # Build EDL edl = build_episode_edl(episode_tl, commit_rec, fps=60, include_cold_open=True) console.print(f"[green]✓[/green] EDL constructed: {len(edl.segments)} segments, {edl.total_frames_60} frames ({edl.total_frames_60/3600:.1f} min)") # Build round specs and grids round_specs = {} grids = {} live_slots = list(range(16)) for r_idx in range(15): spec, grid, solver = build_landscape_round_track(seed, r_idx, live_slots, target_round_s=15.0) round_specs[r_idx] = spec grids[r_idx] = grid live_slots.remove(episode_tl.rounds[r_idx].outcome.eliminated_slot) # Render a ~35-second highlight broadcast sample (2100 frames) covering Cold Open, Roster Card, Round 1 Race, Deciding Moment, and Elimination Sting max_frames = 2100 console.print(f"[bold cyan]2. Rendering 1080p60 MP4 with Procedural Audio ({max_frames} frames)...[/bold cyan]") t_render = time.perf_counter() render_episode_mp4( edl=edl, episode_tl=episode_tl, commit_rec=commit_rec, round_specs=round_specs, grids=grids, out_mp4=out_mp4, quality="draft", max_frames=max_frames, ) render_time = time.perf_counter() - t_render console.print(f"[green]✓[/green] Video rendered in {render_time:.1f}s ({max_frames/render_time:.1f} fps) to [bold]{out_mp4}[/bold]") # Thumbnail & Chapters thumb_path = Path("out/league_thumbnail_sample.png") generate_thumbnail(episode_tl, commit_rec, thumb_path) console.print(f"[green]✓[/green] Thumbnail generated at [bold]{thumb_path}[/bold]") chapters = generate_episode_chapters(edl, episode_tl, commit_rec) desc = format_youtube_description(episode_tl, commit_rec, chapters) desc_path = Path("out/episode_metadata.txt") desc_path.write_text(desc) console.print(f"[green]✓[/green] Description & Chapters saved to [bold]{desc_path}[/bold]") if __name__ == "__main__": main()