I'll complete this comprehensive AI Movie Generator system.
Here's the
continuation and completion of the code:
# ===== AUDIO PROCESSOR =====
class AudioProcessor:
"""Handles audio processing, mixing, and effects"""
def __init__(self):
[Link](frequency=Config.SAMPLE_RATE, size=-16,
channels=Config.AUDIO_CHANNELS)
def process_scene_audio(self, scene: Scene, dialogue_path: str =
None, background_music: bool = True) -> str:
"""Process and mix audio for a scene"""
try:
audio_segments = []
# Add dialogue if available
if dialogue_path and [Link](dialogue_path):
dialogue = AudioSegment.from_file(dialogue_path)
audio_segments.append(dialogue)
# Add background music if requested
if background_music:
bg_music = self._generate_background_music([Link],
[Link])
if bg_music:
audio_segments.append(bg_music)
# Mix all audio segments
if audio_segments:
final_audio = audio_segments[0]
for segment in audio_segments[1:]:
final_audio = final_audio.overlay(segment)
# Ensure audio matches scene duration
target_duration = int([Link] * 1000)
if len(final_audio) > target_duration:
final_audio = final_audio[:target_duration]
elif len(final_audio) < target_duration:
silence =
[Link](duration=target_duration - len(final_audio))
final_audio = final_audio + silence
# Export processed audio
audio_filename =
f"scene_{[Link]}_processed_{int([Link]())}.mp3"
audio_path = [Link](Config.OUTPUT_DIR, "audio",
audio_filename)
final_audio.export(audio_path, format="mp3")
[Link](f"Processed audio for scene {[Link]}")
return audio_path
return None
except Exception as e:
[Link](f"Error processing scene audio: {e}")
return None
def _generate_background_music(self, mood: str, duration: float) -
> AudioSegment:
"""Generate simple background music based on mood"""
try:
# Define mood-based frequencies and patterns
mood_configs = {
"happy": {"base_freq": 440, "pattern": [1, 1.25, 1.5,
2], "volume": -20},
"sad": {"base_freq": 220, "pattern": [1, 1.2, 1.4],
"volume": -25},
"tense": {"base_freq": 330, "pattern": [1, 1.1, 1.3,
1.6], "volume": -15},
"mysterious": {"base_freq": 200, "pattern": [1, 1.3,
1.7], "volume": -30},
"neutral": {"base_freq": 350, "pattern": [1, 1.5],
"volume": -25}
}
config = mood_configs.get([Link](),
mood_configs["neutral"])
base_freq = config["base_freq"]
pattern = config["pattern"]
volume = config["volume"]
# Generate tones
segment_duration = duration * 1000 / len(pattern)
music_segments = []
for multiplier in pattern:
freq = base_freq * multiplier
tone =
Sine(freq).to_audio_segment(duration=segment_duration)
tone = tone + volume # Adjust volume
music_segments.append(tone)
# Combine segments
background_music = sum(music_segments)
# Fade in and out
background_music =
background_music.fade_in(500).fade_out(500)
return background_music
except Exception as e:
[Link](f"Error generating background music: {e}")
return None
# ===== VIDEO PROCESSOR =====
class VideoProcessor:
"""Handles video creation, editing, and rendering"""
def __init__(self):
self.temp_files = []
def create_scene_video(self, scene: Scene, image_path: str,
audio_path: str = None) -> str:
"""Create a video clip for a single scene"""
try:
if not [Link](image_path):
[Link](f"Image file not found: {image_path}")
return None
# Create image clip
image_clip = ImageClip(image_path,
duration=[Link])
# Add subtle zoom effect for visual interest
image_clip = image_clip.resize(lambda t: 1 + 0.02 * t)
# Add audio if available
if audio_path and [Link](audio_path):
audio_clip = AudioFileClip(audio_path)
# Ensure audio duration matches video
if audio_clip.duration > [Link]:
audio_clip = audio_clip.subclip(0, [Link])
elif audio_clip.duration < [Link]:
# Loop audio if it's shorter than video
loops_needed = int([Link] /
audio_clip.duration) + 1
audio_clip = concatenate_audioclips([audio_clip] *
loops_needed)
audio_clip = audio_clip.subclip(0, [Link])
image_clip = image_clip.set_audio(audio_clip)
# Add text overlay for dialogue
if [Link]():
dialogue_text = [Link][:100] + "..." if
len([Link]) > 100 else [Link]
text_clip = TextClip(dialogue_text,
fontsize=50,
color='white',
font='Arial-Bold',
stroke_color='black',
stroke_width=2)
text_clip = text_clip.set_position(('center',
'bottom')).set_duration([Link])
image_clip = CompositeVideoClip([image_clip,
text_clip])
# Export scene video
video_filename =
f"scene_{[Link]}_{int([Link]())}.mp4"
video_path = [Link](Config.OUTPUT_DIR, "video",
video_filename)
image_clip.write_videofile(
video_path,
fps=Config.DEFAULT_FPS,
codec='libx264',
audio_codec='aac',
temp_audiofile=f'temp-audio-{[Link]}.m4a',
remove_temp=True,
verbose=False,
logger=None
)
self.temp_files.append(video_path)
[Link](f"Created video for scene {[Link]}:
{video_path}")
return video_path
except Exception as e:
[Link](f"Error creating scene video: {e}")
return None
def compile_final_movie(self, scene_videos: List[str],
output_path: str, title: str = "AI Generated Movie") -> str:
"""Compile all scene videos into final movie"""
try:
if not scene_videos:
[Link]("No scene videos to compile")
return None
# Filter out None values and non-existent files
valid_videos = [v for v in scene_videos if v and
[Link](v)]
if not valid_videos:
[Link]("No valid scene videos found")
return None
# Load video clips
clips = []
for video_path in valid_videos:
try:
clip = VideoFileClip(video_path)
[Link](clip)
except Exception as e:
[Link](f"Could not load video
{video_path}: {e}")
if not clips:
[Link]("No video clips could be loaded")
return None
# Create title card
title_clip = self._create_title_card(title, duration=3)
if title_clip:
[Link](0, title_clip)
# Create end credits
credits_clip = self._create_credits_card(duration=2)
if credits_clip:
[Link](credits_clip)
# Concatenate all clips
final_video = concatenate_videoclips(clips,
method="compose")
# Add fade transitions
final_video = final_video.fadein(1).fadeout(1)
# Write final video
final_video.write_videofile(
output_path,
fps=Config.DEFAULT_FPS,
codec='libx264',
audio_codec='aac',
bitrate=Config.DEFAULT_BITRATE,
temp_audiofile='temp-audio-final.m4a',
remove_temp=True,
verbose=False,
logger=None
)
# Clean up clips
for clip in clips:
[Link]()
final_video.close()
[Link](f"Final movie compiled: {output_path}")
return output_path
except Exception as e:
[Link](f"Error compiling final movie: {e}")
return None
def _create_title_card(self, title: str, duration: float = 3) ->
VideoClip:
"""Create a title card for the movie"""
try:
# Create title image
img = [Link]('RGB', Config.DEFAULT_RESOLUTION,
color=(0, 0, 0))
draw = [Link](img)
try:
font = [Link]("[Link]", 80)
subtitle_font = [Link]("[Link]", 40)
except:
font = ImageFont.load_default()
subtitle_font = ImageFont.load_default()
# Calculate text position
bbox = [Link]((0, 0), title, font=font)
text_width = bbox[2] - bbox[0]
text_height = bbox[3] - bbox[1]
x = (Config.DEFAULT_RESOLUTION[0] - text_width) // 2
y = (Config.DEFAULT_RESOLUTION[1] - text_height) // 2
# Draw title
[Link]((x, y), title, fill=(255, 255, 255), font=font)
[Link]((x, y + 100), "An AI Generated Film", fill=(200,
200, 200), font=subtitle_font)
# Save title image
title_image_path = [Link](Config.TEMP_DIR,
f"title_{int([Link]())}.png")
[Link](title_image_path)
self.temp_files.append(title_image_path)
# Create video clip
title_clip = ImageClip(title_image_path,
duration=duration)
return title_clip
except Exception as e:
[Link](f"Error creating title card: {e}")
return None
def _create_credits_card(self, duration: float = 2) -> VideoClip:
"""Create end credits card"""
try:
img = [Link]('RGB', Config.DEFAULT_RESOLUTION,
color=(0, 0, 0))
draw = [Link](img)
try:
font = [Link]("[Link]", 60)
except:
font = ImageFont.load_default()
credits_text = [
"THE END",
"",
"Created with AI Movie Generator",
"Powered by OpenAI, Gemini, Stability AI, ElevenLabs"
]
y_offset = 300
for line in credits_text:
if line:
bbox = [Link]((0, 0), line, font=font)
text_width = bbox[2] - bbox[0]
x = (Config.DEFAULT_RESOLUTION[0] - text_width) //
2
[Link]((x, y_offset), line, fill=(255, 255,
255), font=font)
y_offset += 80
credits_image_path = [Link](Config.TEMP_DIR,
f"credits_{int([Link]())}.png")
[Link](credits_image_path)
self.temp_files.append(credits_image_path)
credits_clip = ImageClip(credits_image_path,
duration=duration)
return credits_clip
except Exception as e:
[Link](f"Error creating credits card: {e}")
return None
def cleanup_temp_files(self):
"""Clean up temporary files"""
for file_path in self.temp_files:
try:
if [Link](file_path):
[Link](file_path)
except Exception as e:
[Link](f"Could not remove temp file
{file_path}: {e}")
self.temp_files.clear()
# ===== PROJECT MANAGER =====
class ProjectManager:
"""Manages movie projects and persistence"""
def __init__(self):
self.db_path = [Link](Config.PROJECTS_DIR,
"[Link]")
self._init_database()
def _init_database(self):
"""Initialize SQLite database for projects"""
try:
with [Link](self.db_path) as conn:
[Link]("""
CREATE TABLE IF NOT EXISTS projects (
id TEXT PRIMARY KEY,
title TEXT NOT NULL,
script TEXT,
genre TEXT,
duration_minutes INTEGER,
created_at TIMESTAMP,
output_path TEXT,
status TEXT,
project_data BLOB
)
""")
[Link]()
except Exception as e:
[Link](f"Error initializing database: {e}")
def save_project(self, project: MovieProject) -> bool:
"""Save a movie project to database"""
try:
project_data = [Link](project)
with [Link](self.db_path) as conn:
[Link]("""
INSERT OR REPLACE INTO projects
(id, title, script, genre, duration_minutes,
created_at, output_path, status, project_data)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
""", (
[Link],
[Link],
[Link],
[Link],
project.duration_minutes,
project.created_at,
project.output_path,
[Link],
project_data
))
[Link]()
[Link](f"Saved project: {[Link]}")
return True
except Exception as e:
[Link](f"Error saving project: {e}")
return False
def load_project(self, project_id: str) -> Optional[MovieProject]:
"""Load a movie project from database"""
try:
with [Link](self.db_path) as conn:
cursor = [Link](
"SELECT project_data FROM projects WHERE id = ?",
(project_id,)
)
row = [Link]()
if row:
project = [Link](row[0])
[Link](f"Loaded project: {[Link]}")
return project
except Exception as e:
[Link](f"Error loading project: {e}")
return None
def list_projects(self) -> List[Dict]:
"""List all projects"""
try:
with [Link](self.db_path) as conn:
cursor = [Link]("""
SELECT id, title, genre, duration_minutes,
created_at, status
FROM projects ORDER BY created_at DESC
""")
projects = []
for row in [Link]():
[Link]({
'id': row[0],
'title': row[1],
'genre': row[2],
'duration_minutes': row[3],
'created_at': row[4],
'status': row[5]
})
return projects
except Exception as e:
[Link](f"Error listing projects: {e}")
return []
def delete_project(self, project_id: str) -> bool:
"""Delete a project"""
try:
with [Link](self.db_path) as conn:
[Link]("DELETE FROM projects WHERE id = ?",
(project_id,))
[Link]()
[Link](f"Deleted project: {project_id}")
return True
except Exception as e:
[Link](f"Error deleting project: {e}")
return False
# ===== MAIN APPLICATION GUI =====
class AIMovieGeneratorApp:
"""Main application class with CustomTkinter GUI"""
def __init__(self):
[Link] = [Link]()
[Link]("AI Movie Generator v2.0")
[Link]("1400x900")
[Link](1200, 800)
# Initialize components
self.ai_service = AIServiceManager()
self.audio_processor = AudioProcessor()
self.video_processor = VideoProcessor()
self.project_manager = ProjectManager()
# Application state
self.current_project = None
self.progress_queue = [Link]()
self.is_generating = False
# Setup directories
Config.setup_directories()
# Initialize GUI
self._setup_gui()
self._setup_progress_monitoring()
[Link]("AI Movie Generator initialized")
def _setup_gui(self):
"""Setup the main GUI interface"""
# Configure grid weights
[Link].grid_columnconfigure(1, weight=1)
[Link].grid_rowconfigure(0, weight=1)
# Create main frames
self._create_sidebar()
self._create_main_content()
self._create_status_bar()
def _create_sidebar(self):
"""Create the sidebar with navigation and controls"""
self.sidebar_frame = [Link]([Link], width=300,
corner_radius=0)
self.sidebar_frame.grid(row=0, column=0, rowspan=2,
sticky="nsew")
self.sidebar_frame.grid_rowconfigure(10, weight=1)
# Logo/Title
self.logo_label = [Link](
self.sidebar_frame,
text="🎬 AI Movie\nGenerator",
font=[Link](size=24, weight="bold")
)
self.logo_label.grid(row=0, column=0, padx=20, pady=(20, 10))
# Navigation buttons
self.nav_buttons = {}
nav_items = [
("🏠 Home", self._show_home_tab),
("📝 Script", self._show_script_tab),
("🎭 Scenes", self._show_scenes_tab),
("🎨 Generation", self._show_generation_tab),
("📁 Projects", self._show_projects_tab),
("⚙️Settings", self._show_settings_tab)
]
for i, (text, command) in enumerate(nav_items, 1):
btn = [Link](
self.sidebar_frame,
text=text,
command=command,
height=40,
font=[Link](size=14)
)
[Link](row=i, column=0, padx=20, pady=5, sticky="ew")
self.nav_buttons[text] = btn
# Project info
self.project_info_frame = [Link](self.sidebar_frame)
self.project_info_frame.grid(row=8, column=0, padx=20,
pady=20, sticky="ew")
self.project_title_label = [Link](
self.project_info_frame,
text="No Project Loaded",
font=[Link](size=12, weight="bold")
)
self.project_title_label.pack(pady=5)
self.project_details_label = [Link](
self.project_info_frame,
text="",
font=[Link](size=10)
)
self.project_details_label.pack(pady=2)
# Quick actions
self.quick_actions_frame = [Link](self.sidebar_frame)
self.quick_actions_frame.grid(row=9, column=0, padx=20,
pady=10, sticky="ew")
[Link](
self.quick_actions_frame,
text="Quick Actions",
font=[Link](size=12, weight="bold")
).pack(pady=5)
self.new_project_btn = [Link](
self.quick_actions_frame,
text="New Project",
command=self._new_project,
height=30
)
self.new_project_btn.pack(pady=2, padx=10, fill="x")
self.save_project_btn = [Link](
self.quick_actions_frame,
text="Save Project",
command=self._save_project,
height=30
)
self.save_project_btn.pack(pady=2, padx=10, fill="x")
self.generate_movie_btn = [Link](
self.quick_actions_frame,
text="🎬 Generate Movie",
command=self._start_movie_generation,
height=35,
font=[Link](size=12, weight="bold"),
fg_color=Config.SUCCESS_COLOR,
hover_color="#1e7e34"
)
self.generate_movie_btn.pack(pady=10, padx=10, fill="x")
def _create_main_content(self):
"""Create the main content area with tabs"""
self.main_frame = [Link]([Link])
self.main_frame.grid(row=0, column=1, sticky="nsew", padx=10,
pady=10)
self.main_frame.grid_columnconfigure(0, weight=1)
self.main_frame.grid_rowconfigure(0, weight=1)
# Create tabview
[Link] = [Link](self.main_frame)
[Link](row=0, column=0, sticky="nsew", padx=10,
pady=10)
# Add tabs
self._create_home_tab()
self._create_script_tab()
self._create_scenes_tab()
self._create_generation_tab()
self._create_projects_tab()
self._create_settings_tab()
# Show home tab by default
[Link]("Home")
def _create_home_tab(self):
"""Create the home/welcome tab"""
home_tab = [Link]("Home")
# Welcome section
welcome_frame = [Link](home_tab)
welcome_frame.pack(fill="x", padx=20, pady=20)
[Link](
welcome_frame,
text="Welcome to AI Movie Generator",
font=[Link](size=28, weight="bold")
).pack(pady=20)
[Link](
welcome_frame,
text="Create amazing movies using the power of AI",
font=[Link](size=16)
).pack(pady=10)
# Features section
features_frame = [Link](home_tab)
features_frame.pack(fill="both", expand=True, padx=20,
pady=10)
[Link](
features_frame,
text="Features",
font=[Link](size=20, weight="bold")
).pack(pady=10)
features_text = """
🤖 AI Script Generation - Create compelling scripts with OpenAI
GPT
🎭 Scene Analysis - Break down scripts into scenes with Google
Gemini
🎨 Image Generation - Generate stunning visuals with Stability
AI
Voice Synthesis - Create realistic voices with ElevenLabs
🎬 Video Compilation - Automatically compile your movie
📁 Project Management - Save and manage multiple projects
⚙️Customizable Settings - Adjust generation parameters
"""
[Link](
features_frame,
text=features_text,
font=[Link](size=14),
justify="left"
).pack(pady=20, padx=20)
# Getting started section
getting_started_frame = [Link](home_tab)
getting_started_frame.pack(fill="x", padx=20, pady=10)
[Link](
getting_started_frame,
text="Getting Started",
font=[Link](size=18, weight="bold")
).pack(pady=10)
steps_text = """
1. Configure your API keys in Settings
2. Create a new project or load an existing one
3. Generate or write your script
4. Review and edit scenes
5. Generate your movie!
"""
[Link](
getting_started_frame,
text=steps_text,
font=[Link](size=14),
justify="left"
).pack(pady=10, padx=20)
def _create_script_tab(self):
"""Create the script editing tab"""
script_tab = [Link]("Script")
# Script generation controls
controls_frame = [Link](script_tab)
controls_frame.pack(fill="x", padx=10, pady=10)
# Row 1: Basic settings
row1_frame = [Link](controls_frame)
row1_frame.pack(fill="x", padx=10, pady=5)
[Link](row1_frame, text="Movie
Title:").pack(side="left", padx=5)
self.title_entry = [Link](row1_frame,
placeholder_text="Enter movie title")
self.title_entry.pack(side="left", padx=5, fill="x",
expand=True)
[Link](row1_frame, text="Genre:").pack(side="left",
padx=5)
self.genre_combo = [Link](
row1_frame,
values=[[Link] for genre in MovieGenre],
width=120
)
self.genre_combo.pack(side="left", padx=5)
[Link](row1_frame, text="Duration
(min):").pack(side="left", padx=5)
self.duration_entry = [Link](row1_frame,
placeholder_text="5", width=60)
self.duration_entry.pack(side="left", padx=5)
# Row 2: Prompt and generation
row2_frame = [Link](controls_frame)
row2_frame.pack(fill="x", padx=10, pady=5)
[Link](row2_frame, text="Script
Prompt:").pack(anchor="w", padx=5, pady=2)
self.prompt_entry = [Link](
row2_frame,
placeholder_text="Describe your movie idea...",
height=40
)
self.prompt_entry.pack(fill="x", padx=5, pady=2)
self.generate_script_btn = [Link](
row2_frame,
text="🤖 Generate Script",
command=self._generate_script,
height=35
)
self.generate_script_btn.pack(side="right", padx=5, pady=5)
# Script editor
editor_frame = [Link](script_tab)
editor_frame.pack(fill="both", expand=True, padx=10, pady=10)
[Link](
editor_frame,
text="Script Editor",
font=[Link](size=16, weight="bold")
).pack(pady=5)
self.script_textbox = [Link](editor_frame, height=400)
self.script_textbox.pack(fill="both", expand=True, padx=10,
pady=10)
# Script actions
actions_frame = [Link](editor_frame)
actions_frame.pack(fill="x", padx=10, pady=5)
self.load_script_btn = [Link](
actions_frame,
text="📁 Load Script",
command=self._load_script_file
)
self.load_script_btn.pack(side="left", padx=5)
self.save_script_btn = [Link](
actions_frame,
text="💾 Save Script",
command=self._save_script_file
)
self.save_script_btn.pack(side="left", padx=5)
self.analyze_script_btn = [Link](
actions_frame,
text="🔍 Analyze Scenes",
command=self._analyze_script
)
self.analyze_script_btn.pack(side="right", padx=5)
def _create_scenes_tab(self):
"""Create the scenes management tab"""
scenes_tab = [Link]("Scenes")
# Scenes list
list_frame = [Link](scenes_tab)
list_frame.pack(side="left", fill="both", expand=True,
padx=10, pady=10)
[Link](
list_frame,
text="Scenes",
font=[Link](size=16, weight="bold")
).pack(pady=5)
# Scenes scrollable frame
self.scenes_scrollable = [Link](list_frame,
height=400)
self.scenes_scrollable.pack(fill="both", expand=True, padx=10,
pady=10)
# Scene details
details_frame = [Link](scenes_tab)
details_frame.pack(side="right", fill="both", expand=True,
padx=10, pady=10)
[Link](
details_frame,
text="Scene Details",
font=[Link](size=16, weight="bold")
).pack(pady=5)
# Scene editor form
form_frame = [Link](details_frame, height=400)
form_frame.pack(fill="both", expand=True, padx=10, pady=10)