Spaces:
Runtime error
Runtime error
File size: 3,225 Bytes
4def516 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
from moviepy.editor import *
from PIL import Image, GifImagePlugin
import tempfile
import gradio as gr
def get_video_detail(video_path):
info = VideoFileClip(video_path)
return 0, info.duration, info.fps, max(info.size)
def convert_video_to_gif(
input: str,
start: float = 0,
end: float | None = None,
fps: int | None = None,
quality: int | None = None
) -> Image.Image:
"""
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).
Returns:
Image.Image: GIF image
Examples:
>>> convert_video_to_gif("input.mp4")
"""
# 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))
clip = clip.set_fps(fps)
# Create a temporary file
with tempfile.NamedTemporaryFile(suffix='.gif') as temp_file:
# Write the GIF to the temporary file
clip.write_gif(temp_file.name)
# Read the GIF from the temporary file
gif_image = Image.open(temp_file.name)
return gif_image
with gr.Blocks(
theme = gr.themes.Base(
font = [gr.themes.GoogleFont("Outfit"), "Arial", "sans-serif"],
),
delete_cache=(86400, 86400)
) as demo:
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
)
run_btn = gr.Button("Convert")
output = gr.Gallery(
label="GIF",
format="gif"
)
input.change(
fn=lambda x: x,
inputs=input,
outputs=save,
queue=False,
api_name=False
).then(
fn=get_video_detail,
inputs=save,
outputs=[start, end, fps, quality],
queue=False,
api_name=False
)
run_btn.click(
fn=convert_video_to_gif,
inputs=[save, start, end, fps, quality],
outputs=output,
api_name="convert"
)
if __name__ == "__main__":
demo.queue(max_size=20).launch(show_error=True) |