|
import gradio as gr |
|
from moviepy.editor import VideoFileClip |
|
import os |
|
from PIL import Image |
|
import tempfile |
|
import logging |
|
|
|
|
|
logging.basicConfig(level=logging.INFO) |
|
|
|
|
|
def get_video_info(video): |
|
logging.info("Getting video info") |
|
if not video: |
|
return "No video uploaded." |
|
clip = VideoFileClip(video) |
|
duration = clip.duration |
|
clip.close() |
|
return f"Duration: {duration:.2f} seconds" |
|
|
|
|
|
def generate-thumbnails(video, start_time, end_time): |
|
logging.info("Generating thumbnails") |
|
if not video: |
|
return "No video uploaded." |
|
clip = VideoFileClip(video) |
|
if start_time > clip.duration: |
|
start_img = None |
|
else: |
|
start_frame = clip.get_frame(start_time) |
|
start_img = Image.fromarray(start_frame) |
|
if end_time > clip.duration: |
|
end_img = None |
|
else: |
|
end_frame = clip.get_frame(end_time) |
|
end_img = Image.fromarray(end_frame) |
|
clip.close() |
|
return start_img, end_img |
|
|
|
|
|
def generate_gif(video, start_time, end_time, resolution, frame_rate, playback_speed, loop_count): |
|
logging.info("Generating GIF") |
|
if not video: |
|
return None, None |
|
clip = VideoFileClip(video) |
|
|
|
if start_time > clip.duration: |
|
start_time = 0 |
|
if end_time > clip.duration: |
|
end_time = clip.duration |
|
subclip = clip.subclip(start_time, end_time) |
|
|
|
subclip = subclip.set_fps(subclip.fps * playback_speed) |
|
|
|
if resolution != subclip.size[0]: |
|
ratio = resolution / subclip.size[0] |
|
new_height = int(subclip.size[1] * ratio) |
|
subclip = subclip.resize((resolution, new_height)) |
|
|
|
with tempfile.NamedTemporaryFile(delete=False, suffix=".gif") as temp: |
|
gif_path = temp.name |
|
subclip.write_gif(gif_path, fps=frame_rate, loop=loop_count) |
|
|
|
preview = Image.open(gif_path) |
|
return preview, gif_path |
|
|
|
|
|
with gr.Blocks() as demo: |
|
gr.Markdown("<h1>Video to GIF Converter</h1>") |
|
|
|
|
|
video_input = gr.Video(label="Upload Video") |
|
|
|
|
|
with gr.Row(): |
|
get_info_button = gr.Button("Get Video Info") |
|
video_info = gr.Textbox(label="Video Information") |
|
|
|
|
|
video_output = gr.Video(label="Uploaded Video") |
|
|
|
|
|
start_time = gr.Number(label="Start Time (seconds)", value=0) |
|
end_time = gr.Number(label="End Time (seconds)", value=0) |
|
|
|
|
|
with gr.Row(): |
|
start_thumbnail = gr.Image(label="Start Thumbnail") |
|
end_thumbnail = gr.Image(label="End Thumbnail") |
|
|
|
|
|
resolution = gr.Slider(100, 1920, step=100, value=1920, label="Resolution") |
|
frame_rate = gr.Slider(1, 30, step=1, value=10, label="Frame Rate") |
|
playback_speed = gr.Slider(0.1, 2.0, step=0.1, value=1.0, label="Playback Speed") |
|
loop_count = gr.Slider(0, 10, step=1, value=0, label="GIF Loop Count (0 for infinite)") |
|
|
|
|
|
generate_button = gr.Button("GIF 생성") |
|
|
|
|
|
gif_preview = gr.Image(label="GIF Preview") |
|
gif_download = gr.Download(label="Download GIF") |
|
|
|
|
|
get_info_button.click(get_video_info, inputs=video_input, outputs=video_info) |
|
video_input.change(lambda x: x, inputs=video_input, outputs=video_output) |
|
video_input.change(generate-thumbnails, inputs=[video_input, start_time, end_time], outputs=[start_thumbnail, end_thumbnail]) |
|
generate_button.click(generate_gif, |
|
inputs=[video_input, start_time, end_time, resolution, frame_rate, playback_speed, loop_count], |
|
outputs=[gif_preview, gif_download]) |
|
|
|
demo.launch() |