Video_generator / app.py
parthraninga's picture
Update app.py
03ec8a3 verified
Raw History Blame Contribute Delete
10.1 kB
import gradio as gr
import google.generativeai as genai
import os
import re
import tempfile
import shutil
from pathlib import Path
import time
from moviepy.editor import *
from PIL import Image, ImageDraw, ImageFont
import numpy as np
# Check if API key is available
api_key = os.getenv("GEMINI_API_KEY")
if not api_key:
print("⚠️ Warning: GEMINI_API_KEY not found in environment variables")
print("Please set your Gemini API key in the Hugging Face Spaces secrets")
# Configure Gemini API
if api_key:
genai.configure(api_key=api_key)
model = genai.GenerativeModel(
model_name="gemini-1.5-flash",
generation_config={
"temperature": 0.3,
"top_p": 0.95,
"top_k": 40,
"max_output_tokens": 8000,
}
)
def create_text_clip(text, duration=3, fontsize=48, color='black', bg_color='white', size=(1280, 720)):
"""Create a video clip with text using PIL and MoviePy"""
# Create image with text
img = Image.new('RGB', size, bg_color)
draw = ImageDraw.Draw(img)
# Try to use a default font, fallback to basic if not available
try:
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", fontsize)
except:
try:
font = ImageFont.truetype("arial.ttf", fontsize)
except:
font = ImageFont.load_default()
# Calculate text position (centered)
bbox = draw.textbbox((0, 0), text, font=font)
text_width = bbox[2] - bbox[0]
text_height = bbox[3] - bbox[1]
position = ((size[0] - text_width) // 2, (size[1] - text_height) // 2)
# Draw text
draw.text(position, text, fill=color, font=font)
# Convert PIL image to numpy array
img_array = np.array(img)
# Create video clip
clip = ImageClip(img_array, duration=duration)
return clip
def generate_video(topic, duration_minutes=1):
if not api_key:
return None, "❌ Error: GEMINI_API_KEY not configured. Please set it in Hugging Face Spaces secrets."
try:
# Step 1: Generate content plan
planning_prompt = f"""
Create a simple presentation plan for the topic: "{topic}"
Requirements:
- Create 10-11 slides maximum for {duration_minutes} minute(s)
- Each slide should have ONE clear, concise message (max 10 words)
- Start with a title slide
- Include 3-4 key points about the topic
- End with a conclusion slide
- Keep text simple and readable
Format your response as:
Slide 1: [Title text][details in points]
Slide 2: [Key point 1][details in points]
Slide 3: [Key point 2][details in points]
Slide 4: [Key point 3][details in points]
Slide 5: [Conclusion][details in points]
Example for "Python Programming":
Slide 1 – Python Programming Basics
What is Python?
High-level, general-purpose language
Popular for web, data, AI, automation, and more
Slide 2 – Why Python?
Versatile and widely used in multiple industries
Large community and active development
Open-source and free to use
Slide 3 – Easy to Learn and Read
English-like syntax for easy understanding
Minimal boilerplate code
Example: print("Hello, World!")
Slide 4 – Python's Key Features
Cross-platform compatibility
Large standard library
Object-oriented and functional programming support
Interactive interpreter
Slide 5 – Powerful Libraries Available
Data Analysis: NumPy, Pandas
Visualization: Matplotlib, Seaborn
Web Development: Django, Flask
Machine Learning: TensorFlow, PyTorch
Slide 6 – Popular Use Cases
Web and app development
Data science and analytics
Artificial intelligence and machine learning
Game development
Automation and scripting
Slide 7 – Great for Beginners
Clear documentation and tutorials
Friendly learning curve
Lots of free resources available online
Slide 8 – Tools You’ll Need
Python interpreter (python.org)
Code editor (VS Code, PyCharm, Sublime Text)
Optional: Jupyter Notebook for interactive coding
Slide 9 – Start Your Python Journey!
Install Python and set up your editor
Practice with small programs daily
Work on mini-projects to gain confidence
Join coding communities for support
Slide 10 – Resources to Learn Python
Official Python documentation
FreeCodeCamp, Real Python, W3Schools
Online coding platforms (HackerRank, LeetCode)
"""
plan_response = model.generate_content(planning_prompt)
plan = plan_response.text.strip()
# Parse the slides from the plan
slides = []
for line in plan.split('\n'):
if line.strip() and 'Slide' in line and ':' in line:
slide_text = line.split(':', 1)[1].strip()
if slide_text:
slides.append(slide_text)
if not slides:
return None, f"❌ Could not parse slides from plan:\n{plan}"
# Create video clips
clips = []
slide_duration = max(3, (duration_minutes * 60) / len(slides)) # At least 3 seconds per slide
for i, slide_text in enumerate(slides):
if i == 0: # Title slide
clip = create_text_clip(slide_text, duration=slide_duration, fontsize=56, color='navy')
else: # Content slides
clip = create_text_clip(slide_text, duration=slide_duration, fontsize=42, color='darkblue')
clips.append(clip)
# Concatenate all clips
final_video = concatenate_videoclips(clips, method="compose")
# Save video
timestamp = int(time.time())
output_file = f"video_{timestamp}.mp4"
final_video.write_videofile(
output_file,
fps=24,
codec='libx264',
audio_codec='aac' if final_video.audio else None,
temp_audiofile='temp-audio.m4a',
remove_temp=True
)
# Clean up
final_video.close()
for clip in clips:
clip.close()
success_msg = f"""βœ… Video generated successfully using MoviePy!
**πŸ“‹ Slides Created:**
{chr(10).join([f"{i+1}. {slide}" for i, slide in enumerate(slides)])}
**🎬 Video Details:**
- Duration: {duration_minutes} minute(s)
- Slides: {len(slides)}
- Resolution: 1280x720
- FPS: 24
**πŸ“ Original Plan:**
{plan}
"""
return output_file, success_msg
except Exception as e:
return None, f"❌ Error generating video: {str(e)}"
# Create Gradio interface
with gr.Blocks(title="AI Video Generator", theme=gr.themes.Soft()) as demo:
gr.Markdown("""
# 🎬 AI Video Generator (MoviePy Edition)
Generate educational videos using AI and MoviePy!
**Features:**
- πŸ€– AI-powered content generation using Gemini
- πŸŽ₯ Clean slide-based videos using MoviePy
- ⏱️ Customizable duration (1-3 minutes)
- πŸ“± Simple, professional presentation style
- ☁️ Fully compatible with Hugging Face Spaces
**Note:** Video generation takes 30-90 seconds.
""")
with gr.Row():
with gr.Column(scale=2):
topic_input = gr.Textbox(
label="πŸ“ Video Topic",
placeholder="Enter an educational topic (e.g., 'Introduction to Python', 'Basic Math Concepts')",
value="Introduction to Python Programming",
lines=2
)
duration_input = gr.Slider(
minimum=1,
maximum=3,
value=1,
step=1,
label="⏱️ Duration (minutes)",
info="Shorter durations generate faster"
)
generate_btn = gr.Button("πŸš€ Generate Video", variant="primary", size="lg")
with gr.Column(scale=1):
gr.Markdown("""
### πŸ’‘ Tips for Best Results:
- Use clear, educational topics
- Simple topics work better
- Shorter durations are faster
- Educational content works best
### 🎯 Great Topic Examples:
- "Introduction to Python"
- "Basic Math Operations"
- "How Plants Grow"
- "Understanding Colors"
- "Solar System Facts"
- "Healthy Eating Tips"
""")
with gr.Row():
with gr.Column():
video_output = gr.Video(
label="πŸŽ₯ Generated Video",
height=400
)
with gr.Column():
log_output = gr.Textbox(
label="πŸ“‹ Generation Details",
lines=15,
max_lines=25,
show_copy_button=True,
placeholder="Generation logs and AI-created content will appear here..."
)
# Progress indicator
with gr.Row():
status_text = gr.Textbox(
label="πŸ“Š Status",
value="Ready to generate video - MoviePy edition loaded",
interactive=False
)
def generate_with_status(topic, duration):
yield None, "πŸ”„ Starting video generation...", "πŸ”„ Generating content with AI..."
try:
result_video, result_log = generate_video(topic, duration)
if result_video:
yield result_video, result_log, "βœ… Video generated successfully!"
else:
yield None, result_log, "❌ Video generation failed"
except Exception as e:
yield None, f"❌ Error: {str(e)}", "❌ Generation failed with error"
generate_btn.click(
fn=generate_with_status,
inputs=[topic_input, duration_input],
outputs=[video_output, log_output, status_text],
show_progress=True
)
if __name__ == "__main__":
print("🎬 Starting AI Video Generator with MoviePy...")
demo.launch(
server_name="0.0.0.0" if os.getenv("SPACE_ID") else "127.0.0.1",
server_port=7860,
show_error=True
)