Spaces:
Sleeping
Sleeping
File size: 10,131 Bytes
083a7da 03ec8a3 083a7da 03ec8a3 083a7da 03ec8a3 083a7da 03ec8a3 083a7da |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 |
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
)
|