Spaces:
Runtime error
Runtime error
| import os | |
| import tempfile | |
| from flask import Flask, request, jsonify, send_from_directory | |
| from PIL import Image, ImageDraw | |
| import numpy as np | |
| import imageio | |
| from gtts import gTTS | |
| import torch | |
| from diffusers import DiffusionPipeline, DPMSolverMultistepScheduler | |
| import uuid | |
| # Initialize Flask App | |
| # The 'static_folder' serves files like CSS and JS. | |
| app = Flask(__name__, static_folder='static') | |
| # Create a directory for generated files if it doesn't exist | |
| GENERATED_DIR = os.path.join(os.path.dirname(__file__), 'generated') | |
| os.makedirs(GENERATED_DIR, exist_ok=True) | |
| # ========== LOAD MODELS (Done once on startup) ========== | |
| device = "cuda" if torch.cuda.is_available() else "cpu" | |
| video_pipe = DiffusionPipeline.from_pretrained( | |
| "cerspense/zeroscope_v2_576w", | |
| torch_dtype=torch.float16 | |
| ) | |
| video_pipe.scheduler = DPMSolverMultistepScheduler.from_config(video_pipe.scheduler.config) | |
| video_pipe.to(device) | |
| app.logger.info("AI Models loaded successfully.") | |
| # ========== HELPER FUNCTIONS (Your existing logic) ========== | |
| def story_to_prompt(story): | |
| prompt = story.strip() | |
| return f"{prompt}, cinematic, beautiful, hd, high quality, detailed" | |
| def generate_explainer_character(name, size=(150,150)): | |
| # Your character generation logic here... | |
| img = Image.new("RGB", size, (255, 255, 255)) | |
| draw = ImageDraw.Draw(img) | |
| draw.text((10, 10), f"{name} avatar", fill="black") | |
| return img | |
| def generate_code_explanation(story, prompt): | |
| # Your code explanation logic here... | |
| return f"The code processed the story: '{story}' into a prompt for the AI." | |
| # ========== FLASK ROUTES ========== | |
| # Route to serve the main HTML page | |
| def index(): | |
| return send_from_directory('.', 'index.html') | |
| # Route to serve generated files (videos, audio) | |
| def generated_files(filename): | |
| return send_from_directory(GENERATED_DIR, filename) | |
| # The main API endpoint to handle story-to-video requests | |
| def animate(): | |
| story = request.json.get('story') | |
| if not story: | |
| return jsonify({"error": "No story provided"}), 400 | |
| app.logger.info(f"Received story: {story}") | |
| try: | |
| # 1. Generate Video | |
| prompt = story_to_prompt(story) | |
| video_frames = video_pipe(prompt, num_inference_steps=25, height=320, width=576, num_frames=24).frames | |
| # Save files with unique names to avoid conflicts | |
| unique_id = str(uuid.uuid4()) | |
| video_filename = f"{unique_id}.mp4" | |
| video_path = os.path.join(GENERATED_DIR, video_filename) | |
| imageio.mimsave(video_path, video_frames, fps=12) | |
| video_url = f"/generated/{video_filename}" | |
| # 2. Generate Story Explanation & Audio | |
| story_explanation_text = f"We used an AI to turn your story into a video! The story was about: '{story}'." | |
| audio_filename = f"{unique_id}.mp3" | |
| audio_path = os.path.join(GENERATED_DIR, audio_filename) | |
| tts = gTTS(story_explanation_text, lang='en') | |
| tts.save(audio_path) | |
| audio_url = f"/generated/{audio_filename}" | |
| # 3. Generate Code Explanation | |
| code_explanation_text = generate_code_explanation(story, prompt) | |
| app.logger.info(f"Successfully generated video and audio for story.") | |
| # 4. Send all data back to the frontend as JSON | |
| return jsonify({ | |
| "video_url": video_url, | |
| "story_explanation": story_explanation_text, | |
| "audio_url": audio_url, | |
| "code_explanation": code_explanation_text, | |
| "prompt": prompt | |
| }) | |
| except Exception as e: | |
| app.logger.error(f"An error occurred: {e}") | |
| return jsonify({"error": "Failed to generate animation."}), 500 | |
| if __name__ == '__main__': | |
| # Use 0.0.0.0 to be accessible within the Docker network | |
| app.run(host='0.0.0.0', port=5000, debug=True) |