| # import gradio as gr | |
| # import os | |
| # import shutil | |
| # import tempfile | |
| # from moviepy.editor import ( | |
| # AudioFileClip, | |
| # ImageClip, | |
| # concatenate_videoclips | |
| # ) | |
| # from PIL import Image | |
| # # ------------------------------- | |
| # # Helper: Pillow resize (HF-safe) | |
| # # ------------------------------- | |
| # def resize_image(img_path, size=(1280, 720)): | |
| # pil_img = Image.open(img_path).convert("RGB") | |
| # if hasattr(Image, "Resampling"): | |
| # resample = Image.Resampling.LANCZOS | |
| # else: | |
| # resample = Image.ANTIALIAS # fallback (older Pillow) | |
| # pil_img = pil_img.resize(size, resample) | |
| # pil_img.save(img_path) | |
| # # ------------------------------- | |
| # # Main function | |
| # # ------------------------------- | |
| # def create_video(image_files, audio_file): | |
| # temp_dir = tempfile.mkdtemp() | |
| # image_dir = os.path.join(temp_dir, "images") | |
| # os.makedirs(image_dir, exist_ok=True) | |
| # # Copy & resize images | |
| # for img in image_files: | |
| # dst = os.path.join(image_dir, os.path.basename(img.name)) | |
| # shutil.copy(img.name, dst) | |
| # resize_image(dst) | |
| # # Load audio | |
| # audio = AudioFileClip(audio_file.name) | |
| # audio_duration = audio.duration | |
| # images = sorted(os.listdir(image_dir)) | |
| # img_duration = audio_duration / len(images) | |
| # clips = [] | |
| # for img in images: | |
| # clip = ( | |
| # ImageClip(os.path.join(image_dir, img)) | |
| # .set_duration(img_duration) | |
| # .fadein(0.5) | |
| # .fadeout(0.5) | |
| # ) | |
| # clips.append(clip) | |
| # video = concatenate_videoclips(clips, method="compose") | |
| # final_video = video.set_audio(audio) | |
| # output_path = os.path.join(temp_dir, "final_video.mp4") | |
| # final_video.write_videofile( | |
| # output_path, | |
| # fps=24, | |
| # codec="libx264", | |
| # audio_codec="aac" | |
| # ) | |
| # return output_path | |
| # # ------------------------------- | |
| # # Gradio UI | |
| # # ------------------------------- | |
| # app = gr.Interface( | |
| # fn=create_video, | |
| # inputs=[ | |
| # gr.File(file_types=["image"], file_count="multiple", label="Upload Images"), | |
| # gr.File(file_types=["audio"], label="Upload Audio") | |
| # ], | |
| # outputs=gr.Video(label="Generated Video"), | |
| # title="πΌοΈ Image to Video Generator", | |
| # description="Upload multiple images and one audio file to generate a video." | |
| # ) | |
| # app.launch() | |
| import os | |
| import shutil | |
| import tempfile | |
| import gradio as gr | |
| from PIL import Image | |
| from moviepy.editor import AudioFileClip, ImageClip, concatenate_videoclips | |
| # ------------------------------- | |
| # Core logic: Image + Audio β Video | |
| # ------------------------------- | |
| def create_video(image_files, audio_file): | |
| if not image_files or not audio_file: | |
| raise gr.Error("Please upload images and audio") | |
| temp_dir = tempfile.mkdtemp() | |
| image_dir = os.path.join(temp_dir, "images") | |
| os.makedirs(image_dir, exist_ok=True) | |
| # Copy images | |
| for img in image_files: | |
| shutil.copy(img.name, os.path.join(image_dir, os.path.basename(img.name))) | |
| images = sorted(os.listdir(image_dir)) | |
| audio = AudioFileClip(audio_file.name) | |
| duration_per_image = audio.duration / len(images) | |
| clips = [] | |
| for img in images: | |
| clips.append( | |
| ImageClip(os.path.join(image_dir, img)) | |
| .set_duration(duration_per_image) | |
| .fadein(0.4) | |
| .fadeout(0.4) | |
| ) | |
| final_video = concatenate_videoclips(clips, method="compose").set_audio(audio) | |
| output_path = os.path.join(temp_dir, "final_video.mp4") | |
| final_video.write_videofile( | |
| output_path, | |
| fps=24, | |
| codec="libx264", | |
| audio_codec="aac" | |
| ) | |
| return output_path | |
| # ------------------------------- | |
| # Helpers | |
| # ------------------------------- | |
| def load_uploaded_images(files): | |
| imgs = [] | |
| if files: | |
| for f in files: | |
| img = Image.open(f.name) | |
| imgs.append(img) | |
| return imgs | |
| def set_audio(choice): | |
| return choice | |
| # ------------------------------- | |
| # UI | |
| # ------------------------------- | |
| with gr.Blocks(css_paths="style.css") as demo: | |
| # ---------- HEADER ---------- | |
| gr.HTML(""" | |
| <div class="header-container"> | |
| <img src="https://www.gstatic.com/lamda/images/gemini_favicon_f069958c85030456e93de685481c559f160ea06b.png"> | |
| <div> | |
| <h1>Image + Audio to Video Generator</h1> | |
| <p> | |
| Powered by <a href="https://gradio.app/">Gradio</a> β‘ | | |
| Built by <strong>Mohd Danish</strong> | | |
| <a href="https://linktr.ee/mohddanish" target="_blank">Linktree</a> | |
| </p> | |
| </div> | |
| </div> | |
| """) | |
| # ---------- MAIN ---------- | |
| with gr.Row(): | |
| with gr.Column(): | |
| image_input = gr.File( | |
| file_types=["image"], | |
| file_count="multiple", | |
| label="πΈ Upload Images", | |
| elem_classes="upload-box" | |
| ) | |
| audio_input = gr.File( | |
| file_types=["audio", "video"], | |
| label="π΅ Upload Audio", | |
| elem_classes="upload-box" | |
| ) | |
| submit_btn = gr.Button("π¬ Generate Video", elem_classes="generate-btn") | |
| with gr.Column(): | |
| uploaded_gallery = gr.Gallery(label="Uploaded Images") | |
| video_output = gr.Video(label="Generated Video") | |
| submit_btn.click( | |
| fn=create_video, | |
| inputs=[image_input, audio_input], | |
| outputs=video_output | |
| ) | |
| image_input.upload( | |
| fn=create_video, | |
| inputs=image_input, | |
| outputs=uploaded_gallery | |
| ) | |
| # ---------- EXAMPLES ---------- | |
| gr.Markdown("## Try these examples", elem_classes="gr-examples-header") | |
| gr.Examples( | |
| examples=[ | |
| [ | |
| ["image_data/lenskar-air-la-e11482-c2-eyeglasses_11.png"], | |
| ["image_data/lenskar-air-la-e11482-c2-eyeglasses_21.png"], | |
| ["image_data/lenskar-air-la-e11482-c2-eyeglasses_22.png"], | |
| ["image_data/lenskar-air-la-e11482-c2-eyeglasses_24.png"], | |
| ["image_data/lenskar-air-la-e11482-c2-eyeglasses_5.png"], | |
| ["image_data/lenskar-air-la-e11482-c2-eyeglasses_7.png"], | |
| ["image_data/lenskar-air-la-e12709-c2-eyeglasses_7.png"], | |
| ["image_data/lenskar-air-la-e12709-c2-eyeglasses_9.png"], | |
| ], | |
| ["audio_data/new12 audio.mp3"] | |
| ], | |
| inputs=[image_input, audio_input], | |
| elem_id="examples-grid" | |
| ) | |
| demo.queue(max_size=50).launch(share=True) | |
| # import gradio as gr | |
| # import os | |
| # import shutil | |
| # import tempfile | |
| # from moviepy.editor import ( | |
| # AudioFileClip, | |
| # ImageClip, | |
| # concatenate_videoclips | |
| # ) | |
| # # ------------------------------- | |
| # # Main function | |
| # # ------------------------------- | |
| # def create_video(image_files, audio_file): | |
| # # Temporary working directory | |
| # temp_dir = tempfile.mkdtemp() | |
| # image_dir = os.path.join(temp_dir, "images") | |
| # os.makedirs(image_dir, exist_ok=True) | |
| # # Copy uploaded images | |
| # for img in image_files: | |
| # dst = os.path.join(image_dir, os.path.basename(img.name)) | |
| # shutil.copy(img.name, dst) | |
| # images = sorted(os.listdir(image_dir)) | |
| # if not images: | |
| # raise ValueError("No images uploaded") | |
| # # Load audio (mp3 / wav / mp4 all supported) | |
| # audio = AudioFileClip(audio_file.name) | |
| # audio_duration = audio.duration | |
| # # Each image duration | |
| # img_duration = audio_duration / len(images) | |
| # clips = [] | |
| # for img in images: | |
| # clip = ( | |
| # ImageClip(os.path.join(image_dir, img)) | |
| # .set_duration(img_duration) | |
| # .fadein(0.5) | |
| # .fadeout(0.5) | |
| # ) | |
| # clips.append(clip) | |
| # # Combine clips | |
| # video = concatenate_videoclips(clips, method="compose") | |
| # final_video = video.set_audio(audio) | |
| # # Output file | |
| # output_path = os.path.join(temp_dir, "final_video.mp4") | |
| # final_video.write_videofile( | |
| # output_path, | |
| # fps=24, | |
| # codec="libx264", | |
| # audio_codec="aac" | |
| # ) | |
| # return output_path | |
| # # ------------------------------- | |
| # # Gradio UI | |
| # # ------------------------------- | |
| # # ------------------------------- | |
| # # Gradio UI (UI ONLY MODIFIED) | |
| # # ------------------------------- | |
| # with gr.Blocks(css_paths="style.css") as demo: | |
| # # ---------- HEADER ---------- | |
| # gr.HTML( | |
| # """ | |
| # <div class="header-container"> | |
| # <div> | |
| # <img src="https://www.gstatic.com/lamda/images/gemini_favicon_f069958c85030456e93de685481c559f160ea06b.png" alt="Gemini logo"> | |
| # </div> | |
| # <div> | |
| # <h1>Image to Video Generator</h1> | |
| # <p> | |
| # Powered by <a href="https://gradio.app/">Gradio</a> β‘οΈ | | |
| # Built by <strong>Mohd Danish</strong> | | |
| # <a href="https://linktr.ee/admin/links" target="_blank">My Linktree</a> | |
| # </p> | |
| # </div> | |
| # </div> | |
| # """ | |
| # ) | |
| # # ---------- INSTRUCTIONS ---------- | |
| # with gr.Accordion("π Usage Instructions", open=False): | |
| # gr.Markdown(""" | |
| # - Upload **multiple images** | |
| # - Upload **audio or video** (mp3 / wav / mp4) | |
| # - Click **Generate Video** | |
| # - Original image size is preserved | |
| # """) | |
| # # ---------- MAIN CONTENT ---------- | |
| # with gr.Row(elem_classes="main-content"): | |
| # # ---- INPUT COLUMN ---- | |
| # with gr.Column(scale=1, elem_classes="input-column"): | |
| # image_input = gr.File( | |
| # file_types=["image"], | |
| # file_count="multiple", | |
| # label="πΈ Upload Images", | |
| # elem_classes="upload-box" | |
| # ) | |
| # audio_input = gr.File( | |
| # file_types=["audio", "video"], | |
| # label="π΅ Upload Audio (mp3 / wav / mp4)", | |
| # elem_classes="upload-box" | |
| # ) | |
| # submit_btn = gr.Button( | |
| # "π¬ Generate Video", | |
| # elem_classes="generate-btn" | |
| # ) | |
| # # ---- OUTPUT COLUMN ---- | |
| # with gr.Column(scale=1, elem_classes="output-column"): | |
| # video_output = gr.Video( | |
| # label="π₯ Generated Video", | |
| # elem_classes="output-video" | |
| # ) | |
| # # ---------- CLICK EVENT (LOGIC SAME) ---------- | |
| # submit_btn.click( | |
| # fn=create_video, | |
| # inputs=[image_input, audio_input], | |
| # outputs=video_output | |
| # ) | |
| # image_input.upload( | |
| # fn=create_video, | |
| # inputs=[image_input], | |
| # outputs=[uploaded_gallery], | |
| # ) | |
| # gr.Markdown("## Try these examples", elem_classes="gr-examples-header") | |
| # examples = [ | |
| # ["image_data/lenskar-air-la-e11482-c2-eyeglasses_11.png"], | |
| # ["image_data/lenskar-air-la-e11482-c2-eyeglasses_21.png"], | |
| # ["image_data/lenskar-air-la-e11482-c2-eyeglasses_22.png"], | |
| # ["image_data/lenskar-air-la-e11482-c2-eyeglasses_25.png"], | |
| # ["image_data/lenskar-air-la-e11482-c2-eyeglasses_3.png"], | |
| # ["image_data/lenskar-air-la-e11482-c2-eyeglasses_5.png"], | |
| # ["image_data/lenskar-air-la-e11482-c2-eyeglasses_7.png"], | |
| # ["image_data/lenskar-air-la-e12709-c2-eyeglasses_7.png"], | |
| # ["image_data/lenskar-air-la-e12709-c2-eyeglasses_9.png"], | |
| # ["audio_data/new12 audio.mp3"], | |
| # ["audio_data/Jis_pe_rakhe_tumne_kadam_Sitaare_-_Arijit_Singh_lyricsreels_songlyrics_lyricsvideo_lyricalstatus_128KBPS (2).mp4"], | |
| # ] | |
| # gr.Examples( | |
| # examples=examples, | |
| # inputs=[image_input, prompt_input,], | |
| # elem_id="examples-grid" | |
| # ) | |
| # demo.queue(max_size=50).launch(mcp_server=True, share=True) | |
| # with gr.Blocks(css_paths="style.css") as demo: | |
| # # Custom HTML header with proper class for styling | |
| # gr.HTML( | |
| # """ | |
| # <div class="header-container"> | |
| # <div> | |
| # <img src="https://www.gstatic.com/lamda/images/gemini_favicon_f069958c85030456e93de685481c559f160ea06b.png" alt="Gemini logo"> | |
| # </div> | |
| # <div> | |
| # <h1>Gemini for Image Editing</h1> | |
| # <p> | |
| # Powered by <a href="https://gradio.app/">Gradio</a> β‘οΈ | | |
| # <a href="https://huggingface.co/spaces/ameerazam08/Gemini-Image-Edit?duplicate=true">Duplicate</a> this Repo | | |
| # <a href="https://aistudio.google.com/apikey">Get an API Key</a> | | |
| # Built by <strong>Mohd Danish</strong> | | |
| # <a href="https://linktr.ee/admin/links" target="_blank">My Linktree</a> | |
| # </p> | |
| # </div> | |
| # </div> | |
| # """ | |
| # ) | |
| # with gr.Accordion("β οΈ API Configuration β οΈ", open=False, elem_classes="config-accordion"): | |
| # gr.Markdown(""" | |
| # - **Issue:** β Sometimes the model returns text instead of an image. | |
| # ### π§ Steps to Address: | |
| # 1. **π οΈ Duplicate the Repository** | |
| # - Create a separate copy for modifications. | |
| # 2. **π Use Your Own Gemini API Key** | |
| # - You **must** configure your own Gemini key for generation! | |
| # """) | |
| # with gr.Accordion("π Usage Instructions", open=False, elem_classes="instructions-accordion"): | |
| # gr.Markdown(""" | |
| # ### π Usage | |
| # - Upload an image and enter a prompt to generate outputs. | |
| # - If text is returned instead of an image, it will appear in the text output. | |
| # - Upload **only PNG images** | |
| # - β **Do not use NSFW images!** | |
| # """) | |
| # app = gr.Interface( | |
| # fn=create_video, | |
| # inputs=[ | |
| # gr.File( | |
| # file_types=["image"], | |
| # file_count="multiple", | |
| # label="Upload Images" | |
| # ), | |
| # gr.File( | |
| # file_types=["audio", "video"], # mp3, wav, mp4 supported | |
| # label="Upload Audio (mp3 / wav / mp4)" | |
| # ) | |
| # ], | |
| # outputs=gr.Video(label="Generated Video"), | |
| # title="πΌοΈ Image to Video Generator", | |
| # description="Keeps original image size. Supports any audio format." | |
| # ) | |
| # app.launch() | |