Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import moviepy.editor as mp | |
| import numpy as np | |
| from PIL import Image | |
| import os | |
| # Resize image while maintaining aspect ratio | |
| def resize_image_with_aspect_ratio(img, target_size=(1280, 720), padding_color=(0, 0, 0)): | |
| width, height = img.size | |
| target_width, target_height = target_size | |
| aspect_ratio = width / height | |
| target_aspect_ratio = target_width / target_height | |
| if aspect_ratio > target_aspect_ratio: | |
| new_width = target_width | |
| new_height = int(new_width / aspect_ratio) | |
| else: | |
| new_height = target_height | |
| new_width = int(new_height * aspect_ratio) | |
| img_resized = img.resize((new_width, new_height)) | |
| final_img = Image.new('RGB', target_size, padding_color) | |
| padding_left = (target_width - new_width) // 2 | |
| padding_top = (target_height - new_height) // 2 | |
| final_img.paste(img_resized, (padding_left, padding_top)) | |
| return final_img | |
| # Video generation function with debug logging | |
| def process_and_generate_video(audio_file, images): | |
| debug_log = [] | |
| try: | |
| debug_log.append(f"Audio file received: {audio_file}") | |
| debug_log.append(f"Images received: {images}") | |
| # Process audio file | |
| audio = mp.AudioFileClip(audio_file) | |
| audio_duration = audio.duration | |
| image_clips = [] | |
| image_duration = audio_duration / len(images) | |
| for img_path in images: | |
| try: | |
| debug_log.append(f"Processing image: {img_path}") | |
| img = Image.open(img_path) | |
| resized_img = resize_image_with_aspect_ratio(img, target_size=(1280, 720)) | |
| img_clip = mp.ImageClip(np.array(resized_img)).set_duration(image_duration).set_fps(24) | |
| image_clips.append(img_clip) | |
| except Exception as img_error: | |
| debug_log.append(f"Error processing image {img_path}: {str(img_error)}") | |
| if not image_clips: | |
| raise ValueError("No valid images provided for video generation.") | |
| debug_log.append(f"Created {len(image_clips)} image clips.") | |
| # Concatenate image clips | |
| video = mp.concatenate_videoclips(image_clips, method="compose") | |
| video = video.set_audio(audio) | |
| # Output video path | |
| output_path = '/tmp/generated_video.mp4' | |
| video.write_videofile(output_path, codec='libx264', audio_codec='aac') | |
| debug_log.append(f"Video successfully generated: {output_path}") | |
| print("\n".join(debug_log)) # Print logs to the console for debugging | |
| return output_path | |
| except Exception as e: | |
| debug_log.append(f"Error: {str(e)}") | |
| print("\n".join(debug_log)) # Print logs to the console for debugging | |
| return f"Error: {str(e)}" | |
| # Gradio interface setup | |
| def gradio_interface(): | |
| with gr.Blocks() as demo: | |
| with gr.Row(): | |
| with gr.Column(): | |
| mp3_input = gr.Audio(type="filepath", label="Upload MP3") | |
| # Allow additional formats like .jpeg | |
| image_input = gr.File(type="filepath", file_types=[".jpg", ".png", ".jpeg"], label="Upload Images", file_count="multiple") | |
| generate_button = gr.Button("Generate Video") | |
| output_video = gr.Video(label="Generated Video") | |
| generate_button.click(fn=process_and_generate_video, inputs=[mp3_input, image_input], outputs=output_video) | |
| demo.launch() | |
| # Run the interface | |
| gradio_interface() | |