admin
sync ms
35429ce
raw
history blame
3.1 kB
import os
import math
import gradio as gr
from PIL import Image, ImageSequence
from moviepy.editor import VideoFileClip
from utils import clean_dir, TMP_DIR, EN_US
ZH2EN = {
"上传视频 (请确保上传完整后再点击提交,若时长大于五秒可先在线裁剪)": "Upload video (please ensure the video is completely uploaded before clicking submit, you can crop it online to less than 5s)",
"倍速": "Speed",
"状态栏": "Status",
"文件名": "Filename",
"下载动图": "Download GIF",
}
def _L(zh_txt: str):
return ZH2EN[zh_txt] if EN_US else zh_txt
def get_frame_dur(gif: Image):
# 获取 GIF 图像中第一帧的 duration
dur = gif.info.get("duration", 100)
# 返回每一帧的 duration
return [frame.info.get("duration", dur) for frame in ImageSequence.Iterator(gif)]
def resize_gif(target_width: int, target_height: int, input_gif, output_gif):
gif = Image.open(input_gif)
modified_frames = []
for frame in ImageSequence.Iterator(gif):
resized_frame = frame.resize((target_width, target_height), Image.LANCZOS)
modified_frames.append(resized_frame)
frame_durations = get_frame_dur(gif)
# 将修改后的帧作为新的 GIF 保存
modified_frames[0].save(
output_gif,
format="GIF",
append_images=modified_frames[1:],
save_all=True,
duration=frame_durations,
loop=0,
)
return output_gif
# outer func
def infer(video_path: str, speed: float, target_w=640, cache=f"{TMP_DIR}/gif"):
status = "Success"
gif_name = gif_out = None
try:
clean_dir(cache)
with VideoFileClip(video_path, audio_fps=16000) as clip:
if clip.duration > 5:
raise ValueError("上传的视频过长")
clip.speedx(speed).to_gif(f"{cache}/input.gif", fps=12)
w, h = clip.size
gif_in = f"{cache}/input.gif"
target_h = math.ceil(target_w * h / w)
gif_name = os.path.basename(video_path)
gif_out = resize_gif(target_w, target_h, gif_in, f"{cache}/output.gif")
except Exception as e:
status = f"{e}"
return status, gif_name, gif_out
def video2gif():
example = (
"https://www.modelscope.cn/studio/Genius-Society/online_tools/resolve/master"
if EN_US
else "."
)
return gr.Interface(
fn=infer,
inputs=[
gr.Video(
label=_L(
"上传视频 (请确保上传完整后再点击提交,若时长大于五秒可先在线裁剪)"
)
),
gr.Slider(label=_L("倍速"), minimum=0.5, maximum=2.0, step=0.25, value=1.0),
],
outputs=[
gr.Textbox(label=_L("状态栏"), show_copy_button=True),
gr.Textbox(label=_L("文件名"), show_copy_button=True),
gr.Image(label=_L("下载动图"), type="filepath", show_share_button=False),
],
flagging_mode="never",
examples=[[f"{example}/examples/herta.mp4", 2]],
cache_examples=False,
)