|
import gradio as gr |
|
import os |
|
import sys |
|
|
|
|
|
try: |
|
sys.path.append("/usr/local/lib/python3.10/site-packages") |
|
import moviepy.editor as mp |
|
except ModuleNotFoundError: |
|
print("moviepy ν¨ν€μ§κ° μ€μΉλμ΄ μμ§ μμ΅λλ€. μ€μΉλ₯Ό μ§ν μ€μ
λλ€...") |
|
os.system(f"{sys.executable} -m pip install moviepy") |
|
sys.path.append("/usr/local/lib/python3.10/site-packages") |
|
try: |
|
import moviepy.editor as mp |
|
except ModuleNotFoundError: |
|
print("moviepy λͺ¨λμ λ‘λν μ μμ΅λλ€. μ€μΉ νμΈ ν λ€μ μλνμΈμ.") |
|
sys.exit(1) |
|
|
|
def process_video(video, start_time, end_time, resolution, fps, speed, loop): |
|
try: |
|
|
|
clip = mp.VideoFileClip(video.name) |
|
|
|
|
|
duration = clip.duration |
|
width, height = clip.size |
|
info = { |
|
"duration": duration, |
|
"resolution": f"{width}x{height}" |
|
} |
|
|
|
|
|
start_time = float(start_time) if start_time else 0 |
|
end_time = float(end_time) if end_time else duration |
|
clip = clip.subclip(start_time, end_time) |
|
|
|
|
|
start_thumbnail = clip.get_frame(start_time) if start_time < duration else None |
|
end_thumbnail = clip.get_frame(end_time) if end_time <= duration else None |
|
|
|
|
|
if resolution: |
|
width, height = map(int, resolution.split('x')) |
|
clip = clip.resize((width, height)) |
|
|
|
if fps: |
|
clip = clip.set_fps(int(fps)) |
|
|
|
if speed: |
|
clip = clip.fx(mp.vfx.speedx, float(speed)) |
|
|
|
gif_path = f"output.gif" |
|
clip.write_gif(gif_path, loop=int(loop)) |
|
|
|
return start_thumbnail, end_thumbnail, gif_path, info |
|
except Exception as e: |
|
return None, None, None, {"error": str(e)} |
|
|
|
def main(): |
|
with gr.Blocks() as app: |
|
gr.Markdown("## λμμμ GIFλ‘ λ³ννλ λꡬ") |
|
|
|
with gr.Row(): |
|
video_input = gr.Video(label="λμμ μ
λ‘λ") |
|
video_info = gr.JSON(label="μμ μ 보") |
|
|
|
with gr.Row(): |
|
start_time = gr.Textbox(label="μμ μκ° (μ΄)", placeholder="μ: 0") |
|
end_time = gr.Textbox(label="λ μκ° (μ΄)", placeholder="μ: 10") |
|
|
|
with gr.Row(): |
|
resolution = gr.Textbox(label="ν΄μλ (μ: 640x480)", placeholder="μ: 640x480") |
|
fps = gr.Slider(label="νλ μ μλ (FPS)", minimum=1, maximum=60, step=1, value=24) |
|
speed = gr.Slider(label="μ¬μ μλ (λ°°μ)", minimum=0.1, maximum=3.0, step=0.1, value=1.0) |
|
loop = gr.Slider(label="GIF λ°λ³΅ νμ", minimum=0, maximum=10, step=1, value=0) |
|
|
|
with gr.Row(): |
|
start_thumbnail = gr.Image(label="μμ μΈλ€μΌ") |
|
end_thumbnail = gr.Image(label="λ μΈλ€μΌ") |
|
|
|
gif_preview = gr.Image(label="GIF 미리보기") |
|
gif_download = gr.File(label="GIF λ€μ΄λ‘λ") |
|
|
|
generate_button = gr.Button("GIF μμ±") |
|
|
|
def generate(video, start, end, res, frame_rate, playback_speed, repeat): |
|
return process_video(video, start, end, res, frame_rate, playback_speed, repeat) |
|
|
|
generate_button.click( |
|
generate, |
|
inputs=[video_input, start_time, end_time, resolution, fps, speed, loop], |
|
outputs=[start_thumbnail, end_thumbnail, gif_preview, gif_download] |
|
) |
|
|
|
return app |
|
|
|
if __name__ == "__main__": |
|
app = main() |
|
app.launch() |
|
|