Spaces:
Runtime error
Runtime error
from PIL import Image | |
from moviepy.editor import * | |
import tempfile | |
import gradio as gr | |
def get_video_detail(video_path): | |
if not video_path: | |
return 0, 0, 0, 0, 1.0 | |
else: | |
info = VideoFileClip(video_path) | |
return 0, info.duration, info.fps, max(info.size), 1.0 | |
def convert_video_to_gif( | |
input: str, | |
start: float = 0, | |
end: float | None = None, | |
fps: int | None = None, | |
quality: int | None = None, | |
speed: float = 1.0 # Add the 'speed' parameter | |
): | |
""" | |
Convert video to GIF image | |
Args: | |
input (str): Path to video file. | |
start (float, optional): Start time in seconds. Defaults to 0. | |
end (float, optional): End time in seconds. Defaults to None. | |
fps (int, optional): Frames per second. Defaults to None (max fps). | |
quality (int, optional): Image quality. Defaults to None (max quality). | |
speed (float, optional): Playback speed. Defaults to 1.0 (normal speed). | |
Returns: | |
str: Path to the GIF file | |
Examples: | |
>>> convert_video_to_gif("input.mp4", speed=2.0) | |
""" | |
# Get video input & info | |
clip = VideoFileClip(input) | |
max_fps = clip.fps | |
max_duration = clip.duration | |
max_res = max(clip.size) | |
if end is None: | |
end = max_duration | |
if end > max_duration: | |
raise ValueError(f"End time {end} is longer than video duration {max_duration}") | |
if fps > max_fps: | |
raise ValueError(f"FPS {fps} is greater than video FPS {max_fps}") | |
if quality is None: | |
quality = max_res | |
if quality > max_res: | |
raise ValueError( | |
f"Quality must be less than video max resolution {max_res}, but is {quality}" | |
) | |
clip = clip.subclip(start, end) | |
target_height = quality | |
aspect_ratio = clip.size[0] / clip.size[1] | |
target_width = int(target_height * aspect_ratio) | |
clip = clip.resize((target_width, target_height)) | |
# Set the playback speed | |
clip = clip.fx(vfx.all, speed) | |
clip = clip.set_fps(fps) | |
# Create a temporary file | |
with tempfile.NamedTemporaryFile(suffix=".gif", delete=False) as temp_file: | |
# Write the GIF to the temporary file | |
clip.write_gif(temp_file.name) | |
# Return the path to the GIF file | |
gif_file_path = temp_file.name | |
return gif_file_path | |
# Gradio code... | |
with gr.Blocks( | |
theme = gr.themes.Base( | |
font = [gr.themes.GoogleFont("Outfit"), "Arial", "sans-serif"], | |
), | |
delete_cache=(86400, 86400) | |
) as demo: | |
gr.Markdown(""" | |
# Video To Gif Converter | |
This is a simple tool to convert any video to gif image. Feel free to report any error!! | |
""") | |
input = gr.Video(interactive=True) | |
save = gr.Text(label="Cache path", interactive=False) | |
with gr.Row(): | |
start = gr.Number( | |
label="Start", | |
info="Video start time in seconds", | |
interactive=True | |
) | |
end = gr.Number( | |
label="End", | |
info="Video end time in seconds", | |
interactive=True | |
) | |
with gr.Row(): | |
fps = gr.Number( | |
label="FPS", | |
info="Frame per second", | |
interactive=True | |
) | |
quality = gr.Number( | |
label="Quality", | |
info="Nax resolution available", | |
interactive=True | |
) | |
speed = gr.Number( | |
label="Speed", | |
info="Default speed / Gif speed", | |
interactive=True | |
) | |
run_btn = gr.Button("Convert") | |
output = gr.File( | |
label="GIF" | |
) | |
input.change( | |
fn=lambda video: video, | |
inputs=input, | |
outputs=save, | |
queue=False, | |
api_name="upload" | |
).then( | |
fn=get_video_detail, | |
inputs=save, | |
outputs=[start, end, fps, quality, speed], | |
queue=False, | |
api_name="info" | |
) | |
run_btn.click( | |
fn=convert_video_to_gif, | |
inputs=[save, start, end, fps, quality, speed], | |
outputs=output, | |
api_name="convert" | |
) | |
if __name__ == "__main__": | |
demo.queue(max_size=20).launch(show_error=True) |