Spaces:
Sleeping
Sleeping
| import os | |
| import requests | |
| from moviepy.editor import * | |
| from moviepy.config import change_settings | |
| from elevenlabs import generate, save | |
| import tempfile | |
| # Configure moviepy to use ImageMagick if needed | |
| change_settings({"IMAGEMAGICK_BINARY": "/usr/bin/convert"}) | |
| PEXELS_API_KEY = os.getenv("PEXELS_API_KEY") | |
| ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY") | |
| def create_video(video_script, audio_script, summary): | |
| """Generate complete educational video""" | |
| try: | |
| # Step 1: Generate AI voiceover | |
| audio = generate( | |
| text=audio_script, | |
| voice="Rachel", | |
| model="eleven_monolingual_v2", | |
| api_key=ELEVENLABS_API_KEY | |
| ) | |
| audio_path = os.path.join(tempfile.gettempdir(), "narration.mp3") | |
| save(audio, audio_path) | |
| # Step 2: Parse video script for scenes | |
| scenes = [] | |
| for scene_text in video_script.split("\n\n"): | |
| if "[Visual]:" in scene_text: | |
| scene = { | |
| "visual": scene_text.split("[Visual]:")[1].split("[Voiceover]:")[0].strip(), | |
| "voiceover": scene_text.split("[Voiceover]:")[1].strip() | |
| } | |
| scenes.append(scene) | |
| # Step 3: Get Pexels footage for each scene | |
| video_clips = [] | |
| for scene in scenes: | |
| # Get stock footage | |
| pexels_response = requests.get( | |
| f"https://api.pexels.com/videos/search?query={scene['visual']}&per_page=1", | |
| headers={"Authorization": PEXELS_API_KEY} | |
| ) | |
| video_url = pexels_response.json()['videos'][0]['video_files'][0]['link'] | |
| # Download and process clip | |
| clip = VideoFileClip(video_url).subclip(0, 8) # 8 sec per scene | |
| clip = clip.resize(height=1080) # Standardize size | |
| video_clips.append(clip) | |
| # Step 4: Combine all clips | |
| final_video = concatenate_videoclips(video_clips) | |
| # Step 5: Add audio | |
| audio_clip = AudioFileClip(audio_path) | |
| final_video = final_video.set_audio(audio_clip) | |
| # Step 6: Add subtitles and watermark | |
| def add_subtitle(txt): | |
| return TextClip( | |
| txt, fontsize=40, color='white', | |
| font='Arial-Bold', stroke_color='black', stroke_width=1 | |
| ).set_position(('center', 'bottom')).set_duration(8) | |
| subtitles = [add_subtitle(scene['voiceover']) for scene in scenes] | |
| subtitles = concatenate_videoclips(subtitles) | |
| watermark = (TextClip("MentorMindz", fontsize=30, color='white') | |
| .set_position(('right', 'top')) | |
| .set_duration(final_video.duration)) | |
| final_video = CompositeVideoClip([final_video, subtitles, watermark]) | |
| # Save final video | |
| output_path = os.path.join(tempfile.gettempdir(), "final_output.mp4") | |
| final_video.write_videofile( | |
| output_path, | |
| codec='libx264', | |
| audio_codec='aac', | |
| fps=24 | |
| ) | |
| # Upload to storage (in production use S3/Cloudinary) | |
| return f"https://your-storage.com/{output_path.split('/')[-1]}" | |
| except Exception as e: | |
| raise Exception(f"Video creation failed: {str(e)}") |