video2gif / app.py
kakamond's picture
Upload 2 files
66a8b39 verified
raw
history blame
2.89 kB
import os
import math
import shutil
import gradio as gr
from PIL import Image, ImageSequence
from moviepy.editor import VideoFileClip
TMP_DIR = "./__pycache__"
def clean_cache(tmp_dir=TMP_DIR):
if os.path.exists(tmp_dir):
shutil.rmtree(tmp_dir)
os.mkdir(tmp_dir)
return f"{tmp_dir}/input.gif"
def get_frame_duration(gif: Image):
# 获取 GIF 图像中第一帧的 duration
duration = gif.info.get("duration", 100)
# 返回每一帧的 duration
return [
frame.info.get("duration", duration) for frame in ImageSequence.Iterator(gif)
]
def resize_gif(
target_width: int,
target_height: int,
input_path=f"{TMP_DIR}/input.gif",
output_path=f"{TMP_DIR}/output.gif",
):
# Open the GIF image
gif = Image.open(input_path)
# Create a list to hold the modified frames
modified_frames = []
# Loop through each frame of the GIF
for frame in ImageSequence.Iterator(gif):
# Resize the frame
resized_frame = frame.resize((target_width, target_height), Image.LANCZOS)
# Append the resized frame to the list
modified_frames.append(resized_frame)
frame_durations = get_frame_duration(gif)
# 将修改后的帧作为新的 GIF 保存
modified_frames[0].save(
output_path,
format="GIF",
append_images=modified_frames[1:],
save_all=True,
duration=frame_durations,
loop=0,
)
return output_path
def infer(video_path: str, speed: float):
target_w = 640
gif_path = clean_cache()
try:
with VideoFileClip(video_path, audio_fps=16000) as clip:
if clip.duration > 5:
raise ValueError("上传的视频过长 The uploaded video is too long")
# clip.write_gif(gif_path, fps=12, progress_bar=True)
clip.speedx(speed).to_gif(gif_path, fps=12)
w, h = clip.size
target_h = math.ceil(target_w * h / w)
return os.path.basename(video_path), resize_gif(target_w, target_h)
except Exception as e:
return f"{e}", None
if __name__ == "__main__":
iface = gr.Interface(
fn=infer,
inputs=[
gr.Video(label="上传视频 Upload video"),
gr.Slider(
label="倍速 Speed",
minimum=0.5,
maximum=2.0,
step=0.25,
value=1.0,
),
],
outputs=[
gr.Textbox(label="文件名 Filename"),
gr.Image(label="下载动图 Download GIF", type="filepath"),
],
title="请确保视频上传完整后再点击提交,若时长大于五秒可先在线裁剪<br>Please make sure the video is completely uploaded before clicking Submit, you can crop it online first if the video size is >5s",
allow_flagging="never",
)
iface.launch()