Spaces:
Sleeping
Sleeping
File size: 5,039 Bytes
db3a622 34524fb db3a622 34524fb a163be5 34524fb db3a622 85e550a db3a622 34524fb db3a622 85e550a 34524fb db3a622 34524fb 85e550a 34524fb 85e550a 34524fb db3a622 34524fb db3a622 34524fb db3a622 34524fb db3a622 34524fb db3a622 34524fb db3a622 34524fb db3a622 34524fb 85e550a db3a622 34524fb db3a622 34524fb a163be5 34524fb db3a622 34524fb db3a622 34524fb db3a622 34524fb |
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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
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()
|