Update app.py
Browse files
app.py
CHANGED
@@ -13,7 +13,6 @@ def add_log(message: str):
|
|
13 |
"""
|
14 |
๋ก๊ทธ ๋ฉ์์ง๋ฅผ ์ ์ฅํ๋ ํจ์
|
15 |
"""
|
16 |
-
global global_logs
|
17 |
global_logs.append(message)
|
18 |
print(message)
|
19 |
|
@@ -38,7 +37,6 @@ def generate_thumbnail(video_clip, time_point):
|
|
38 |
return thumbnail_img
|
39 |
except Exception as e:
|
40 |
add_log(f"[ERROR] ์ธ๋ค์ผ ์์ฑ ์คํจ: {e}")
|
41 |
-
# ๋ฒ์๋ฅผ ๋ฒ์ด๋๋ฉด ์ฒซ ํ๋ ์
|
42 |
frame = video_clip.get_frame(0)
|
43 |
thumbnail_img = Image.fromarray(frame)
|
44 |
return thumbnail_img
|
@@ -66,7 +64,7 @@ def adjust_aspect_ratio(clip, option):
|
|
66 |
width, height = clip.size
|
67 |
current_ratio = width / height
|
68 |
|
69 |
-
# ์์์ด ๋๋ฌด
|
70 |
if current_ratio > target_ratio:
|
71 |
new_width = int(height * target_ratio)
|
72 |
new_height = height
|
@@ -74,23 +72,16 @@ def adjust_aspect_ratio(clip, option):
|
|
74 |
new_width = width
|
75 |
new_height = int(width / target_ratio)
|
76 |
|
77 |
-
return clip.crop(
|
78 |
-
x_center=width / 2,
|
79 |
-
y_center=height / 2,
|
80 |
-
width=new_width,
|
81 |
-
height=new_height
|
82 |
-
)
|
83 |
|
84 |
-
def process_video(
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
resolution_scale
|
93 |
-
):
|
94 |
"""
|
95 |
๋์์์ GIF๋ก ๋ณํํ๋ ํจ์
|
96 |
"""
|
@@ -99,7 +90,7 @@ def process_video(
|
|
99 |
|
100 |
add_log("[LOG 1] ๋น๋์ค ์
๋ก๋ ๋ฐ ์ฒ๋ฆฌ ์์")
|
101 |
|
102 |
-
# video ํ๋ผ๋ฏธํฐ์์ ํ์ผ ๊ฒฝ๋ก ์ถ์ถ
|
103 |
video_path = video if isinstance(video, str) else video.name
|
104 |
|
105 |
add_log("[LOG 2] ๋น๋์ค ๋ก๋ ์ค...")
|
@@ -116,7 +107,7 @@ def process_video(
|
|
116 |
start_sec = parse_time_to_seconds(start_time_str)
|
117 |
end_sec = parse_time_to_seconds(end_time_str)
|
118 |
|
119 |
-
# ๋ฒ์ ๋ณด์
|
120 |
if start_sec < 0:
|
121 |
start_sec = 0
|
122 |
if end_sec <= 0 or end_sec > duration:
|
@@ -127,7 +118,6 @@ def process_video(
|
|
127 |
|
128 |
add_log(f"[LOG 5] ์ ์ฉ๋ ์์ ์๊ฐ: {start_sec}์ด, ์ข
๋ฃ ์๊ฐ: {end_sec}์ด")
|
129 |
|
130 |
-
# ์์ ์๋ฅด๊ธฐ
|
131 |
add_log("[LOG 6] ์์ ์๋ฅด๊ธฐ ์์
์งํ...")
|
132 |
clip = input_video.subclip(start_sec, end_sec)
|
133 |
|
@@ -135,44 +125,34 @@ def process_video(
|
|
135 |
add_log(f"[LOG 7] ํ๋ซํผ ๋น์จ ์กฐ์ : {platform_option}")
|
136 |
clip = adjust_aspect_ratio(clip, platform_option)
|
137 |
|
138 |
-
# ์ถ๋ ฅ ํด์๋ ์ถ์
|
139 |
if abs(resolution_scale - 1.0) > 1e-3:
|
140 |
add_log(f"[LOG 7-1] ์ถ๋ ฅ ํด์๋ ์ถ์: {resolution_scale*100:.0f}%")
|
141 |
clip = clip.resize(resolution_scale)
|
142 |
|
143 |
-
# ์ฌ์์๋
|
144 |
if abs(speed_factor - 1.0) > 1e-3:
|
145 |
add_log(f"[LOG 8] ์ฌ์์๋ {speed_factor}๋ฐฐ๋ก ์กฐ์ ์ค...")
|
146 |
clip = clip.fx(mp.vfx.speedx, speed_factor)
|
147 |
|
148 |
-
# ํ๋ ์ ๋ ์ดํธ
|
149 |
original_fps = clip.fps
|
150 |
target_fps = original_fps * frame_rate_factor
|
151 |
add_log(f"[LOG 9] ์ต์ข
์ถ๋ ฅ FPS: {target_fps:.2f} (์๋ณธ FPS: {original_fps})")
|
152 |
clip = clip.set_fps(target_fps)
|
153 |
|
154 |
-
# ๋ฐ๋ณต ํ์
|
155 |
add_log(f"[LOG 10] GIF ๋ฐ๋ณต ํ์ ์ค์ : {repeat_count} (0์ด๋ฉด ๋ฌดํ๋ฐ๋ณต)")
|
156 |
-
# MoviePy์ write_gif์์ loop=N ์ "N+1๋ฒ ์ฌ์"์ ์๋ฏธํฉ๋๋ค.
|
157 |
-
# ์ฌ์ฉ์๊ฐ ์
๋ ฅํ repeat_count = ์ฌ์ ํ์ ๋ก ๋ง์ถ๊ธฐ ์ํด ์๋์ ๊ฐ์ด ์ค์
|
158 |
-
if repeat_count == 0:
|
159 |
-
loop_param = 0 # 0 => infinite
|
160 |
-
else:
|
161 |
-
loop_param = max(repeat_count - 1, 0)
|
162 |
-
|
163 |
final_clip = clip
|
164 |
|
165 |
-
# GIF ์์ฑ
|
166 |
add_log("[LOG 11] GIF ์์ฑ ์ค...")
|
167 |
output_filename = f"temp_{uuid.uuid4().hex}.gif"
|
168 |
try:
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
)
|
175 |
-
add_log("[LOG 12] GIF ์์ฑ ์๋ฃ! ํ์ผ๋ช
: " + output_filename)
|
176 |
except Exception as e:
|
177 |
add_log(f"[ERROR] GIF ์์ฑ ์คํจ: {e}")
|
178 |
return None, None, "\n".join(global_logs)
|
@@ -217,101 +197,61 @@ with gr.Blocks() as demo:
|
|
217 |
with gr.Tab("GIF ๋ณํ"):
|
218 |
# ๋์์ ์
๋ก๋
|
219 |
video_input = gr.Video(label="๋์์ ์
๋ก๋")
|
220 |
-
|
221 |
# ์์/๋ ์๊ฐ ์
๋ ฅ
|
222 |
start_time = gr.Textbox(label="์์ ์๊ฐ (์: 00:00:05)", value="00:00:00")
|
223 |
end_time = gr.Textbox(label="์ข
๋ฃ ์๊ฐ (์: 00:00:10)", value="00:00:05")
|
224 |
-
|
225 |
# ์ธ๋ค์ผ ๋ฏธ๋ฆฌ๋ณด๊ธฐ
|
226 |
start_thumb_output = gr.Image(label="์์ ์ธ๋ค์ผ ๋ฏธ๋ฆฌ๋ณด๊ธฐ")
|
227 |
end_thumb_output = gr.Image(label="์ข
๋ฃ ์ธ๋ค์ผ ๋ฏธ๋ฆฌ๋ณด๊ธฐ")
|
228 |
-
|
229 |
-
# ํ๋ซํผ๋ณ ํด์๋(๋น์จ) ์ ํ (Radio)
|
230 |
platform_option = gr.Radio(
|
231 |
label="ํด์๋/๋น์จ ์ ํ",
|
232 |
-
choices=[
|
233 |
-
"์๋ณธ ์ ์ง",
|
234 |
-
"์ ํ๋ธ (16:9)",
|
235 |
-
"์ผ์ธ /๋ฆด์ค (9:16)",
|
236 |
-
"์ ์ฌ๊ฐํ (1:1)",
|
237 |
-
"์ธ์คํ๊ทธ๋จ (4:5)",
|
238 |
-
"ํด๋์ (4:3)"
|
239 |
-
],
|
240 |
value="์๋ณธ ์ ์ง"
|
241 |
)
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
label="์ถ๋ ฅ ํด์๋ ์ถ์ ๋น์จ (0.1 ~ 1.0)",
|
246 |
-
minimum=0.1,
|
247 |
-
maximum=1.0,
|
248 |
-
step=0.1,
|
249 |
-
value=1.0
|
250 |
-
)
|
251 |
-
|
252 |
# ํ๋ ์ ๋ ์ดํธ, ์ฌ์ ์๋, ๋ฐ๋ณต ํ์ ์กฐ์
|
253 |
-
frame_rate_slider = gr.Slider(
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
)
|
260 |
-
speed_slider = gr.Slider(
|
261 |
-
label="์ฌ์ ์๋ ์กฐ์ (0.5 ~ 5.0)",
|
262 |
-
minimum=0.5,
|
263 |
-
maximum=5.0,
|
264 |
-
step=0.1,
|
265 |
-
value=1.0
|
266 |
-
)
|
267 |
-
repeat_slider = gr.Slider(
|
268 |
-
label="GIF ๋ฐ๋ณต ํ์ (0=๋ฌดํ, 1=1ํ, 2=2ํ, ...)",
|
269 |
-
minimum=0,
|
270 |
-
maximum=10,
|
271 |
-
step=1,
|
272 |
-
value=0
|
273 |
-
)
|
274 |
-
|
275 |
# GIF ์์ฑ ๋ฒํผ ๋ฐ ๊ฒฐ๊ณผ ์ถ๋ ฅ
|
276 |
generate_button = gr.Button("GIF ์์ฑํ๊ธฐ")
|
277 |
gif_preview_output = gr.Image(label="์์ฑ๋ GIF ๋ฏธ๋ฆฌ๋ณด๊ธฐ")
|
278 |
download_output = gr.File(label="GIF ๋ค์ด๋ก๋ ๋งํฌ")
|
279 |
logs_output = gr.Textbox(label="๋ก๊ทธ ์ถ๋ ฅ", lines=10)
|
280 |
|
281 |
-
# ์ธ๋ค์ผ ์
๋ฐ์ดํธ ์ด๋ฒคํธ
|
282 |
-
start_time.change(
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
)
|
292 |
-
video_input.change(
|
293 |
-
fn=update_thumbnails,
|
294 |
-
inputs=[video_input, start_time, end_time],
|
295 |
-
outputs=[start_thumb_output, end_thumb_output]
|
296 |
-
)
|
297 |
-
|
298 |
# GIF ์์ฑ ๋ฒํผ ์ด๋ฒคํธ
|
299 |
generate_button.click(
|
300 |
fn=process_video,
|
301 |
inputs=[
|
302 |
-
video_input,
|
303 |
-
start_time,
|
304 |
-
end_time,
|
305 |
-
platform_option,
|
306 |
-
frame_rate_slider,
|
307 |
-
speed_slider,
|
308 |
-
repeat_slider,
|
309 |
-
resolution_scale_slider
|
310 |
],
|
311 |
outputs=[
|
312 |
-
gif_preview_output,
|
313 |
-
download_output,
|
314 |
-
logs_output
|
315 |
]
|
316 |
)
|
317 |
|
@@ -319,13 +259,11 @@ with gr.Blocks() as demo:
|
|
319 |
"### [์ฌ์ฉ ๊ฐ์ด๋]\n"
|
320 |
"1. ๋์์์ ์
๋ก๋ํ์ธ์.\n"
|
321 |
"2. ์์/๋ ์๊ฐ์ ์
๋ ฅํ์ธ์.\n"
|
322 |
-
"3. ํ๋ซํผ๋ณ ๊ถ์ฅ
|
323 |
-
" `GIF ์์ฑํ๊ธฐ` ๋ฒํผ์ ๋๋ฅด๋ฉด GIF๊ฐ ์์ฑ๋ฉ๋๋ค.\n"
|
324 |
-
" -
|
325 |
-
"
|
326 |
-
"
|
327 |
-
" - 2 โ 2ํ ์ฌ์ ํ ์ข
๋ฃ\n"
|
328 |
-
"4. ๊ฒฐ๊ณผ ๋ฏธ๋ฆฌ๋ณด๊ธฐ์ ๋ค์ด๋ก๋ ๋งํฌ๋ฅผ ํตํด GIF๋ฅผ ํ์ธํ ์ ์์ต๋๋ค."
|
329 |
)
|
330 |
|
331 |
if __name__ == "__main__":
|
|
|
13 |
"""
|
14 |
๋ก๊ทธ ๋ฉ์์ง๋ฅผ ์ ์ฅํ๋ ํจ์
|
15 |
"""
|
|
|
16 |
global_logs.append(message)
|
17 |
print(message)
|
18 |
|
|
|
37 |
return thumbnail_img
|
38 |
except Exception as e:
|
39 |
add_log(f"[ERROR] ์ธ๋ค์ผ ์์ฑ ์คํจ: {e}")
|
|
|
40 |
frame = video_clip.get_frame(0)
|
41 |
thumbnail_img = Image.fromarray(frame)
|
42 |
return thumbnail_img
|
|
|
64 |
width, height = clip.size
|
65 |
current_ratio = width / height
|
66 |
|
67 |
+
# ์์์ด ๋๋ฌด ๋๋ค๋ฉด ๊ฐ๋ก๋ฅผ, ๋๋ฌด ๋๋ค๋ฉด ์ธ๋ก๋ฅผ ํฌ๋กญ
|
68 |
if current_ratio > target_ratio:
|
69 |
new_width = int(height * target_ratio)
|
70 |
new_height = height
|
|
|
72 |
new_width = width
|
73 |
new_height = int(width / target_ratio)
|
74 |
|
75 |
+
return clip.crop(x_center=width / 2, y_center=height / 2, width=new_width, height=new_height)
|
|
|
|
|
|
|
|
|
|
|
76 |
|
77 |
+
def process_video(video,
|
78 |
+
start_time_str,
|
79 |
+
end_time_str,
|
80 |
+
platform_option, # ํ๋ซํผ๋ณ ๋น์จ ์ ํ (Radio)
|
81 |
+
frame_rate_factor, # ํ๋ ์ ๋ ์ดํธ ์ถ์ ๋ฐฐ์จ (1.0์ด๋ฉด ์๋ณธ)
|
82 |
+
speed_factor,
|
83 |
+
repeat_count,
|
84 |
+
resolution_scale): # ์ถ๋ ฅ ํด์๋ ์ถ์ ๋น์จ (1.0์ด๋ฉด ์๋ณธ)
|
|
|
|
|
85 |
"""
|
86 |
๋์์์ GIF๋ก ๋ณํํ๋ ํจ์
|
87 |
"""
|
|
|
90 |
|
91 |
add_log("[LOG 1] ๋น๋์ค ์
๋ก๋ ๋ฐ ์ฒ๋ฆฌ ์์")
|
92 |
|
93 |
+
# video ํ๋ผ๋ฏธํฐ์์ ํ์ผ ๊ฒฝ๋ก ์ถ์ถ (Gradio์์ ๋ฐํํ๋ ๊ฐ์ด ๋ฌธ์์ด์ผ ์ ์์)
|
94 |
video_path = video if isinstance(video, str) else video.name
|
95 |
|
96 |
add_log("[LOG 2] ๋น๋์ค ๋ก๋ ์ค...")
|
|
|
107 |
start_sec = parse_time_to_seconds(start_time_str)
|
108 |
end_sec = parse_time_to_seconds(end_time_str)
|
109 |
|
110 |
+
# ์๊ฐ ๋ฒ์ ๋ณด์
|
111 |
if start_sec < 0:
|
112 |
start_sec = 0
|
113 |
if end_sec <= 0 or end_sec > duration:
|
|
|
118 |
|
119 |
add_log(f"[LOG 5] ์ ์ฉ๋ ์์ ์๊ฐ: {start_sec}์ด, ์ข
๋ฃ ์๊ฐ: {end_sec}์ด")
|
120 |
|
|
|
121 |
add_log("[LOG 6] ์์ ์๋ฅด๊ธฐ ์์
์งํ...")
|
122 |
clip = input_video.subclip(start_sec, end_sec)
|
123 |
|
|
|
125 |
add_log(f"[LOG 7] ํ๋ซํผ ๋น์จ ์กฐ์ : {platform_option}")
|
126 |
clip = adjust_aspect_ratio(clip, platform_option)
|
127 |
|
128 |
+
# ์ถ๋ ฅ ํด์๋ ์ถ์ ์ต์
|
129 |
if abs(resolution_scale - 1.0) > 1e-3:
|
130 |
add_log(f"[LOG 7-1] ์ถ๋ ฅ ํด์๋ ์ถ์: {resolution_scale*100:.0f}%")
|
131 |
clip = clip.resize(resolution_scale)
|
132 |
|
133 |
+
# ์ฌ์์๋ ์กฐ์ : speedx๋ฅผ ์ ์ฉํ๋ฉด clip.duration์ ์ค์ด๋ค์ง๋ง fps๋ ๊ทธ๋๋ก ์ ์ง๋จ.
|
134 |
if abs(speed_factor - 1.0) > 1e-3:
|
135 |
add_log(f"[LOG 8] ์ฌ์์๋ {speed_factor}๋ฐฐ๋ก ์กฐ์ ์ค...")
|
136 |
clip = clip.fx(mp.vfx.speedx, speed_factor)
|
137 |
|
138 |
+
# FPS ์กฐ์ : ์ต์ข
์ถ๋ ฅ FPS๋ ํ๋ ์ ๋ ์ดํธ ๋ฐฐ์จ๋ง ๋ฐ์ (speed_factor๋ ์ด๋ฏธ duration์ ๋ฐ์๋จ)
|
139 |
original_fps = clip.fps
|
140 |
target_fps = original_fps * frame_rate_factor
|
141 |
add_log(f"[LOG 9] ์ต์ข
์ถ๋ ฅ FPS: {target_fps:.2f} (์๋ณธ FPS: {original_fps})")
|
142 |
clip = clip.set_fps(target_fps)
|
143 |
|
144 |
+
# ๋ฐ๋ณต ํ์(0: ๋ฌดํ, 1~10: ์ง์ ํ์)
|
145 |
add_log(f"[LOG 10] GIF ๋ฐ๋ณต ํ์ ์ค์ : {repeat_count} (0์ด๋ฉด ๋ฌดํ๋ฐ๋ณต)")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
146 |
final_clip = clip
|
147 |
|
|
|
148 |
add_log("[LOG 11] GIF ์์ฑ ์ค...")
|
149 |
output_filename = f"temp_{uuid.uuid4().hex}.gif"
|
150 |
try:
|
151 |
+
# ImageMagick์ผ๋ก GIF ์์ฑ (๊ธฐ๋ณธ๊ฐ), loop=0 => ๋ฌดํ
|
152 |
+
# loop=N => GIF๊ฐ ์ด Nํ ์ฌ์ (N=1์ด๋ฉด ์ฌ์ ํ ์ ์ง)
|
153 |
+
loop_param = 0 if int(repeat_count) == 0 else int(repeat_count)
|
154 |
+
final_clip.write_gif(output_filename, fps=target_fps, loop=loop_param)
|
155 |
+
add_log(f"[LOG 12] GIF ์์ฑ ์๋ฃ! ํ์ผ๋ช
: {output_filename}, loop={loop_param}")
|
|
|
|
|
156 |
except Exception as e:
|
157 |
add_log(f"[ERROR] GIF ์์ฑ ์คํจ: {e}")
|
158 |
return None, None, "\n".join(global_logs)
|
|
|
197 |
with gr.Tab("GIF ๋ณํ"):
|
198 |
# ๋์์ ์
๋ก๋
|
199 |
video_input = gr.Video(label="๋์์ ์
๋ก๋")
|
|
|
200 |
# ์์/๋ ์๊ฐ ์
๋ ฅ
|
201 |
start_time = gr.Textbox(label="์์ ์๊ฐ (์: 00:00:05)", value="00:00:00")
|
202 |
end_time = gr.Textbox(label="์ข
๋ฃ ์๊ฐ (์: 00:00:10)", value="00:00:05")
|
|
|
203 |
# ์ธ๋ค์ผ ๋ฏธ๋ฆฌ๋ณด๊ธฐ
|
204 |
start_thumb_output = gr.Image(label="์์ ์ธ๋ค์ผ ๋ฏธ๋ฆฌ๋ณด๊ธฐ")
|
205 |
end_thumb_output = gr.Image(label="์ข
๋ฃ ์ธ๋ค์ผ ๋ฏธ๋ฆฌ๋ณด๊ธฐ")
|
206 |
+
# ํ๋ซํผ๋ณ ํด์๋(๋น์จ) ์ ํ (Radio ๋ฒํผ)
|
|
|
207 |
platform_option = gr.Radio(
|
208 |
label="ํด์๋/๋น์จ ์ ํ",
|
209 |
+
choices=["์๋ณธ ์ ์ง", "์ ํ๋ธ (16:9)", "์ผ์ธ /๋ฆด์ค (9:16)", "์ ์ฌ๊ฐํ (1:1)", "์ธ์คํ๊ทธ๋จ (4:5)", "ํด๋์ (4:3)"],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
210 |
value="์๋ณธ ์ ์ง"
|
211 |
)
|
212 |
+
# ์ถ๋ ฅ ํด์๋ ์ถ์ ์ต์
(1.0์ด๋ฉด ์๋ณธ, 0.1 ~ 1.0 ๋ฒ์)
|
213 |
+
resolution_scale_slider = gr.Slider(label="์ถ๋ ฅ ํด์๋ ์ถ์ ๋น์จ (0.1 ~ 1.0)",
|
214 |
+
minimum=0.1, maximum=1.0, step=0.1, value=1.0)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
215 |
# ํ๋ ์ ๋ ์ดํธ, ์ฌ์ ์๋, ๋ฐ๋ณต ํ์ ์กฐ์
|
216 |
+
frame_rate_slider = gr.Slider(label="ํ๋ ์ ๋ ์ดํธ ๋ฐฐ์จ ์กฐ์ (0.1 ~ 1.0)",
|
217 |
+
minimum=0.1, maximum=1.0, step=0.1, value=1.0)
|
218 |
+
speed_slider = gr.Slider(label="์ฌ์ ์๋ ์กฐ์ (0.5 ~ 5.0)",
|
219 |
+
minimum=0.5, maximum=5.0, step=0.1, value=1.0)
|
220 |
+
repeat_slider = gr.Slider(label="GIF ๋ฐ๋ณต ํ์ (0: ๋ฌดํ๋ฐ๋ณต, 1~10: ๋ฐ๋ณต ํ์)",
|
221 |
+
minimum=0, maximum=10, step=1, value=0)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
222 |
# GIF ์์ฑ ๋ฒํผ ๋ฐ ๊ฒฐ๊ณผ ์ถ๋ ฅ
|
223 |
generate_button = gr.Button("GIF ์์ฑํ๊ธฐ")
|
224 |
gif_preview_output = gr.Image(label="์์ฑ๋ GIF ๋ฏธ๋ฆฌ๋ณด๊ธฐ")
|
225 |
download_output = gr.File(label="GIF ๋ค์ด๋ก๋ ๋งํฌ")
|
226 |
logs_output = gr.Textbox(label="๋ก๊ทธ ์ถ๋ ฅ", lines=10)
|
227 |
|
228 |
+
# ์ธ๋ค์ผ ์
๋ฐ์ดํธ ์ด๋ฒคํธ (๋์์ ๋๋ ์๊ฐ ์
๋ ฅ ๋ณ๊ฒฝ ์)
|
229 |
+
start_time.change(fn=update_thumbnails,
|
230 |
+
inputs=[video_input, start_time, end_time],
|
231 |
+
outputs=[start_thumb_output, end_thumb_output])
|
232 |
+
end_time.change(fn=update_thumbnails,
|
233 |
+
inputs=[video_input, start_time, end_time],
|
234 |
+
outputs=[start_thumb_output, end_thumb_output])
|
235 |
+
video_input.change(fn=update_thumbnails,
|
236 |
+
inputs=[video_input, start_time, end_time],
|
237 |
+
outputs=[start_thumb_output, end_thumb_output])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
238 |
# GIF ์์ฑ ๋ฒํผ ์ด๋ฒคํธ
|
239 |
generate_button.click(
|
240 |
fn=process_video,
|
241 |
inputs=[
|
242 |
+
video_input, # ๋์์ ์
๋ก๋
|
243 |
+
start_time, # ์์ ์๊ฐ
|
244 |
+
end_time, # ์ข
๋ฃ ์๊ฐ
|
245 |
+
platform_option, # ํ๋ซํผ๋ณ ๋น์จ
|
246 |
+
frame_rate_slider, # ํ๋ ์ ๋ ์ดํธ ๋ฐฐ์จ
|
247 |
+
speed_slider, # ์ฌ์ ์๋
|
248 |
+
repeat_slider, # ๋ฐ๋ณต ํ์
|
249 |
+
resolution_scale_slider # ํด์๋ ์ถ์ ๋น์จ
|
250 |
],
|
251 |
outputs=[
|
252 |
+
gif_preview_output, # ์์ฑ๋ GIF ๋ฏธ๋ฆฌ๋ณด๊ธฐ
|
253 |
+
download_output, # GIF ๋ค์ด๋ก๋ ๋งํฌ
|
254 |
+
logs_output # ๋ก๊ทธ ์ถ๋ ฅ
|
255 |
]
|
256 |
)
|
257 |
|
|
|
259 |
"### [์ฌ์ฉ ๊ฐ์ด๋]\n"
|
260 |
"1. ๋์์์ ์
๋ก๋ํ์ธ์.\n"
|
261 |
"2. ์์/๋ ์๊ฐ์ ์
๋ ฅํ์ธ์.\n"
|
262 |
+
"3. ํ๋ซํผ๋ณ ๊ถ์ฅ ํด์๋/๋น์จ(์๋ณธ ์ ์ง, ์ ํ๋ธ, ์ผ์ธ /๋ฆด์ค, ์ ์ฌ๊ฐํ, ์ธ์คํ๊ทธ๋จ, ํด๋์)๊ณผ ์ถ๋ ฅ ํด์๋ ์ถ์ ๋น์จ์ ์ ํํ๊ณ ,\n"
|
263 |
+
" ํ๋ ์ ๋ ์ดํธ ๋ฐฐ์จ, ์ฌ์ ์๋, ๋ฐ๋ณต ํ์๋ฅผ ์กฐ์ ํ ํ `GIF ์์ฑํ๊ธฐ` ๋ฒํผ์ ๋๋ฅด๋ฉด GIF๊ฐ ์์ฑ๋ฉ๋๋ค.\n"
|
264 |
+
" - ๋ฐ๋ณต ํ์(0: ๋ฌดํ๋ฐ๋ณต, 1~10: ์ง์ ํ์). ์) 1์ด๋ฉด 1ํ ์ฌ์ ํ ๋ฉ์ถค, 2์ด๋ฉด 2ํ ์ฌ์, 0์ด๋ฉด ๋ฌดํ๋ฐ๋ณต.\n"
|
265 |
+
"4. ๊ฒฐ๊ณผ ๋ฏธ๋ฆฌ๋ณด๊ธฐ์ ๋ค์ด๋ก๋ ๋งํฌ๋ฅผ ํตํด GIF๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.\n"
|
266 |
+
"โป ๋ฌดํ๋ฐ๋ณต์ด ์๋ ํน์ ๋ฐ๋ณต ํ์๋ฅผ ์ํ ๊ฒฝ์ฐ, ImageMagick์ด ์ค์น๋์ด ์์ด์ผ ํฉ๋๋ค."
|
|
|
|
|
267 |
)
|
268 |
|
269 |
if __name__ == "__main__":
|