import tempfile import gradio as gr from moviepy.editor import VideoFileClip import moviepy.video.io.ffmpeg_tools as ffmpeg_tools # TODO: Finalize result gif size with pygifscicle? https://github.com/LucaCappelletti94/pygifsicle Maybe optimize option # TODO: Extra delay frames? # git lfs track --filename file_example_MP4_480_1_5MG.mp4 def convert_mp4_to_gif(input_video_path, fps): if input_video_path is None: return None # Save the reversed frames as a new GIF with tempfile.NamedTemporaryFile(suffix=".gif", delete=False) as temp_file: temp_filename = temp_file.name # Load the video clip video_clip = VideoFileClip(input_video_path) # Set the desired frame rate (frames per second) for the GIF video_clip = video_clip.set_duration(video_clip.duration) video_clip = video_clip.set_fps(fps) # Export the video as a GIF video_clip.write_gif(temp_filename, program='ffmpeg') # Close the video clip video_clip.close() return [temp_filename] with gr.Blocks() as demo: gr.Markdown(value='# MP4 Converter') with gr.Row(): with gr.Column(scale=1): gr.Markdown('## Load mp4 video to convert to an animated gif') in_video = gr.Video(label="Input mp4", format='mp4') frame_rate = gr.Slider(label="Frames per Second", value=10, minimum=1, maximum=360, step=1, interactive=True) run_button = gr.Button(variant='primary') with gr.Column(scale=1): gr.Markdown('## View the animated gif') image_out = gr.Gallery(label="Animated Gif Image") clear_button = gr.ClearButton(components=[image_out]) in_video.change(convert_mp4_to_gif, [in_video, frame_rate], [image_out]) run_button.click(convert_mp4_to_gif, [in_video, frame_rate], [image_out]) gr.Examples( examples=[['file_example_MP4_480_1_5MG.mp4', 60]], inputs=[in_video, frame_rate], outputs=[image_out], fn=convert_mp4_to_gif, cache_examples=True) with gr.Accordion('Developer Notes:', open=False): gr.Markdown('This simple tool handles a conversion I\'ve needed from time to time.\n\n' 'Note that like many tools working with video this has a dependency on ffmpeg.\n\n' 'An enhancement to this tool would optimize the generated gif to reduce its size.') if __name__ == '__main__': demo.launch()