Gif_test_01 / app.py
aliceblue11's picture
Update app.py
a163be5 verified
import gradio as gr
import moviepy.editor as mp
import imageio
import os
import logging
# 로그 설정
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
def get_video_info(video_path):
try:
clip = mp.VideoFileClip(video_path)
duration = clip.duration
logging.info(f"동영상 재생 시간: {duration}초")
return duration
except Exception as e:
logging.error(f"동영상 정보 추출 실패: {e}")
return None
def generate_thumbnails(video_path, start_time, end_time):
try:
clip = mp.VideoFileClip(video_path)
start_frame = clip.get_frame(start_time)
end_frame = clip.get_frame(end_time)
start_thumb_path = "start_thumbnail.png"
end_thumb_path = "end_thumbnail.png"
imageio.imwrite(start_thumb_path, start_frame)
imageio.imwrite(end_thumb_path, end_frame)
logging.info("썸네일 생성 성공")
return start_thumb_path, end_thumb_path
except Exception as e:
logging.error(f"썸네일 생성 실패: {e}")
return None, None
def create_gif(video_path, start_time, end_time, resolution, fps, speed, repeat):
try:
clip = mp.VideoFileClip(video_path).subclip(start_time, end_time)
# 해상도 조절
if resolution != 100:
new_width = int(clip.w * resolution / 100)
new_height = int(clip.h * resolution / 100)
clip = clip.resize(newsize=(new_width, new_height))
logging.info(f"해상도 조절: {new_width}x{new_height}")
# 프레임 속도 조절
clip = clip.set_fps(fps)
logging.info(f"프레임 속도 조절: {fps}fps")
# 재생 속도 조절
clip = clip.fx(mp.vfx.speedx, speed)
logging.info(f"재생 속도 조절: {speed}배속")
# GIF 반복 설정
if repeat == -1:
loop = 0 # 무한 반복
else:
loop = repeat
gif_path = "output.gif"
clip.write_gif(gif_path, loop=loop)
logging.info("GIF 생성 성공")
return gif_path
except Exception as e:
logging.error(f"GIF 생성 실패: {e}")
return None
def process_video(video, start_time, end_time, resolution, fps, speed, repeat):
if video is None:
logging.warning("업로드된 동영상이 없습니다.")
return None, None
video_path = video # 수정: video.name → video
logging.info(f"동영상 업로드: {video_path}")
# 동영상 정보 추출
duration = get_video_info(video_path)
if duration is None:
logging.error("동영상 정보를 가져올 수 없습니다.")
return None, None
# 썸네일 생성
start_thumb, end_thumb = generate_thumbnails(video_path, start_time, end_time)
if not start_thumb or not end_thumb:
logging.error("썸네일 생성에 실패했습니다.")
return None, None
# GIF 생성
gif_path = create_gif(video_path, start_time, end_time, resolution, fps, speed, repeat)
if gif_path:
logging.info(f"생성된 GIF 경로: {gif_path}")
return gif_path, gif_path
else:
logging.error("GIF 생성에 실패했습니다.")
return None, None
with gr.Blocks() as demo:
gr.Markdown("# 동영상을 GIF로 변환하기")
with gr.Row():
video_input = gr.Video(label="동영상 업로드")
with gr.Row():
video_info = gr.Textbox(label="동영상 재생 시간 (초)", interactive=False)
with gr.Row():
start_time = gr.Number(label="시작 시간 (초)", value=0)
end_time = gr.Number(label="끝 시간 (초)", value=5)
with gr.Row():
start_thumbnail = gr.Image(label="시작 부분 썸네일")
end_thumbnail = gr.Image(label="끝 부분 썸네일")
with gr.Row():
resolution = gr.Slider(label="해상도 조절 (%)", minimum=10, maximum=200, step=10, value=100)
fps = gr.Slider(label="프레임 속도 조절", minimum=1, maximum=60, step=1, value=24)
with gr.Row():
speed = gr.Slider(label="재생 속도 조절", minimum=0.5, maximum=3.0, step=0.1, value=1.0)
repeat = gr.Slider(label="GIF 반복 횟수 (-1은 무한 반복)", minimum=-1, maximum=10, step=1, value=-1)
generate_button = gr.Button("GIF 생성")
with gr.Row():
gif_preview = gr.Image(label="GIF 미리보기")
gif_download = gr.File(label="GIF 다운로드")
def update_video_info(video):
if video is None:
return ""
duration = get_video_info(video) # 수정: video.name → video
return f"{duration:.2f} 초" if duration else "정보 불러오기 실패"
video_input.change(fn=update_video_info, inputs=video_input, outputs=video_info)
generate_button.click(
fn=process_video,
inputs=[video_input, start_time, end_time, resolution, fps, speed, repeat],
outputs=[gif_preview, gif_download]
)
demo.launch()