Spaces:
Running
Running
File size: 3,099 Bytes
7cf86e5 35429ce 7cf86e5 9909b2f 7cf86e5 35429ce 7cf86e5 9909b2f 7cf86e5 9909b2f 7cf86e5 9909b2f 7cf86e5 9909b2f 7cf86e5 9909b2f 7cf86e5 9909b2f 7cf86e5 9909b2f 7cf86e5 b0b394a 35429ce b0b394a 7cf86e5 b0b394a 9909b2f b0b394a 7cf86e5 b0b394a 3359abb 7cf86e5 |
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 |
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,
)
|