ginipick commited on
Commit
569bdec
ยท
verified ยท
1 Parent(s): c057ff1

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +250 -0
app.py ADDED
@@ -0,0 +1,250 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from gradio_client import Client, handle_file
3
+ import logging
4
+ import traceback
5
+ from datetime import datetime
6
+ import json
7
+
8
+ # ๋กœ๊น… ์„ค์ •
9
+ logging.basicConfig(
10
+ level=logging.DEBUG,
11
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
12
+ )
13
+ logger = logging.getLogger(__name__)
14
+
15
+ # API ์—”๋“œํฌ์ธํŠธ
16
+ API_URL = "http://211.233.58.201:7788/"
17
+
18
+ def test_api_connection():
19
+ """API ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ"""
20
+ try:
21
+ client = Client(API_URL)
22
+ logger.info(f"Successfully connected to API: {API_URL}")
23
+ return True, "API ์—ฐ๊ฒฐ ์„ฑ๊ณต!"
24
+ except Exception as e:
25
+ logger.error(f"Failed to connect to API: {str(e)}")
26
+ return False, f"API ์—ฐ๊ฒฐ ์‹คํŒจ: {str(e)}"
27
+
28
+ def generate_animation(image, audio, guidance_scale, steps, progress=gr.Progress()):
29
+ """์• ๋‹ˆ๋ฉ”์ด์…˜ ์ƒ์„ฑ ํ•จ์ˆ˜"""
30
+ logger.info("=== ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ƒ์„ฑ ์‹œ์ž‘ ===")
31
+ logs = []
32
+
33
+ try:
34
+ # ์ž…๋ ฅ ํŒŒ๋ผ๋ฏธํ„ฐ ๋กœ๊น…
35
+ log_msg = f"์ž…๋ ฅ ํŒŒ๋ผ๋ฏธํ„ฐ:\n- Image: {image}\n- Audio: {audio}\n- Guidance Scale: {guidance_scale}\n- Steps: {steps}"
36
+ logger.info(log_msg)
37
+ logs.append(f"[{datetime.now().strftime('%H:%M:%S')}] {log_msg}")
38
+
39
+ # ์ž…๋ ฅ ๊ฒ€์ฆ
40
+ if image is None:
41
+ error_msg = "์ด๋ฏธ์ง€๊ฐ€ ์ œ๊ณต๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค."
42
+ logger.error(error_msg)
43
+ logs.append(f"[{datetime.now().strftime('%H:%M:%S')}] ERROR: {error_msg}")
44
+ return None, None, "\n".join(logs)
45
+
46
+ if audio is None:
47
+ error_msg = "์˜ค๋””์˜ค๊ฐ€ ์ œ๊ณต๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค."
48
+ logger.error(error_msg)
49
+ logs.append(f"[{datetime.now().strftime('%H:%M:%S')}] ERROR: {error_msg}")
50
+ return None, None, "\n".join(logs)
51
+
52
+ # Progress ์—…๋ฐ์ดํŠธ
53
+ progress(0.1, desc="API ํด๋ผ์ด์–ธํŠธ ์ดˆ๊ธฐํ™” ์ค‘...")
54
+
55
+ # API ํด๋ผ์ด์–ธํŠธ ์ƒ์„ฑ
56
+ client = Client(API_URL)
57
+ logs.append(f"[{datetime.now().strftime('%H:%M:%S')}] API ํด๋ผ์ด์–ธํŠธ ์ƒ์„ฑ ์™„๋ฃŒ")
58
+
59
+ # Progress ์—…๋ฐ์ดํŠธ
60
+ progress(0.3, desc="ํŒŒ์ผ ํ•ธ๋“ค ์ƒ์„ฑ ์ค‘...")
61
+
62
+ # ํŒŒ์ผ ํ•ธ๋“ค ์ƒ์„ฑ
63
+ image_handle = handle_file(image)
64
+ audio_handle = handle_file(audio)
65
+
66
+ log_msg = f"ํŒŒ์ผ ํ•ธ๋“ค ์ƒ์„ฑ ์™„๋ฃŒ:\n- Image handle: {type(image_handle)}\n- Audio handle: {type(audio_handle)}"
67
+ logger.debug(log_msg)
68
+ logs.append(f"[{datetime.now().strftime('%H:%M:%S')}] {log_msg}")
69
+
70
+ # Progress ์—…๋ฐ์ดํŠธ
71
+ progress(0.5, desc="API ํ˜ธ์ถœ ์ค‘... (์ด ๊ณผ์ •์€ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค)")
72
+
73
+ # API ํ˜ธ์ถœ
74
+ logger.info("API ํ˜ธ์ถœ ์‹œ์ž‘")
75
+ logs.append(f"[{datetime.now().strftime('%H:%M:%S')}] API ํ˜ธ์ถœ ์‹œ์ž‘...")
76
+
77
+ result = client.predict(
78
+ image_path=image_handle,
79
+ audio_path=audio_handle,
80
+ guidance_scale=guidance_scale,
81
+ steps=steps,
82
+ api_name="/generate_animation"
83
+ )
84
+
85
+ # Progress ์—…๋ฐ์ดํŠธ
86
+ progress(0.9, desc="๊ฒฐ๊ณผ ์ฒ˜๋ฆฌ ์ค‘...")
87
+
88
+ # ๊ฒฐ๊ณผ ๋กœ๊น…
89
+ log_msg = f"API ํ˜ธ์ถœ ์„ฑ๊ณต!\n๊ฒฐ๊ณผ ํƒ€์ž…: {type(result)}\n๊ฒฐ๊ณผ ๊ธธ์ด: {len(result) if isinstance(result, (list, tuple)) else 'N/A'}"
90
+ logger.info(log_msg)
91
+ logs.append(f"[{datetime.now().strftime('%H:%M:%S')}] {log_msg}")
92
+
93
+ # ๊ฒฐ๊ณผ ์ƒ์„ธ ๋กœ๊น…
94
+ if isinstance(result, (list, tuple)) and len(result) >= 2:
95
+ for i, item in enumerate(result):
96
+ log_msg = f"๊ฒฐ๊ณผ[{i}]: {type(item)} - {str(item)[:100]}..."
97
+ logger.debug(log_msg)
98
+ logs.append(f"[{datetime.now().strftime('%H:%M:%S')}] {log_msg}")
99
+
100
+ animation_result = result[0]
101
+ comparison_result = result[1]
102
+
103
+ # ๋น„๋””์˜ค ๊ฒฝ๋กœ ์ถ”์ถœ
104
+ animation_video = None
105
+ comparison_video = None
106
+
107
+ if isinstance(animation_result, dict) and 'video' in animation_result:
108
+ animation_video = animation_result['video']
109
+ logs.append(f"[{datetime.now().strftime('%H:%M:%S')}] ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋น„๋””์˜ค ๊ฒฝ๋กœ: {animation_video}")
110
+
111
+ if isinstance(comparison_result, dict) and 'video' in comparison_result:
112
+ comparison_video = comparison_result['video']
113
+ logs.append(f"[{datetime.now().strftime('%H:%M:%S')}] ๋น„๊ต ๋น„๋””์˜ค ๊ฒฝ๋กœ: {comparison_video}")
114
+
115
+ logs.append(f"[{datetime.now().strftime('%H:%M:%S')}] === ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ƒ์„ฑ ์™„๋ฃŒ! ===")
116
+
117
+ return animation_video, comparison_video, "\n".join(logs)
118
+ else:
119
+ error_msg = f"์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๊ฒฐ๊ณผ ํ˜•์‹: {type(result)}"
120
+ logger.error(error_msg)
121
+ logs.append(f"[{datetime.now().strftime('%H:%M:%S')}] ERROR: {error_msg}")
122
+ return None, None, "\n".join(logs)
123
+
124
+ except Exception as e:
125
+ error_msg = f"์˜ค๋ฅ˜ ๋ฐœ์ƒ: {str(e)}"
126
+ logger.error(error_msg)
127
+ logger.error(traceback.format_exc())
128
+ logs.append(f"[{datetime.now().strftime('%H:%M:%S')}] ERROR: {error_msg}")
129
+ logs.append(f"[{datetime.now().strftime('%H:%M:%S')}] ์ƒ์„ธ ์˜ค๋ฅ˜:\n{traceback.format_exc()}")
130
+ return None, None, "\n".join(logs)
131
+
132
+ # Gradio ์ธํ„ฐํŽ˜์ด์Šค ์ƒ์„ฑ
133
+ with gr.Blocks(title="Animation Generator API Test") as demo:
134
+ gr.Markdown("""
135
+ # ๐ŸŽฌ Animation Generator API Test Interface
136
+
137
+ ์ด ์ธํ„ฐํŽ˜์ด์Šค๋Š” `http://211.233.58.201:7788/` API๋ฅผ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•œ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.
138
+
139
+ ## ์‚ฌ์šฉ ๋ฐฉ๋ฒ•:
140
+ 1. ํฌํŠธ๋ ˆ์ดํŠธ ์ด๋ฏธ์ง€๋ฅผ ์—…๋กœ๋“œํ•˜์„ธ์š”
141
+ 2. ๋“œ๋ผ์ด๋น™ ์˜ค๋””์˜ค ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•˜์„ธ์š”
142
+ 3. Guidance Scale๊ณผ Inference Steps๋ฅผ ์กฐ์ •ํ•˜์„ธ์š”
143
+ 4. "Generate Animation" ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜์„ธ์š”
144
+ """)
145
+
146
+ # API ์—ฐ๊ฒฐ ์ƒํƒœ ํ™•์ธ
147
+ with gr.Row():
148
+ with gr.Column():
149
+ connection_status = gr.Textbox(label="API ์—ฐ๊ฒฐ ์ƒํƒœ", interactive=False)
150
+ check_connection_btn = gr.Button("API ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ", variant="secondary")
151
+
152
+ gr.Markdown("---")
153
+
154
+ # ์ž…๋ ฅ ์„น์…˜
155
+ with gr.Row():
156
+ with gr.Column():
157
+ image_input = gr.Image(
158
+ label="Portrait Image (any aspect ratio)",
159
+ type="filepath",
160
+ elem_id="image_input"
161
+ )
162
+ audio_input = gr.Audio(
163
+ label="Driving Audio",
164
+ type="filepath",
165
+ elem_id="audio_input"
166
+ )
167
+
168
+ with gr.Column():
169
+ guidance_scale = gr.Slider(
170
+ minimum=1,
171
+ maximum=10,
172
+ value=3,
173
+ step=0.1,
174
+ label="Guidance Scale",
175
+ info="Controls the strength of the guidance"
176
+ )
177
+ steps = gr.Slider(
178
+ minimum=1,
179
+ maximum=50,
180
+ value=10,
181
+ step=1,
182
+ label="Inference Steps",
183
+ info="Number of denoising steps"
184
+ )
185
+
186
+ generate_btn = gr.Button("๐Ÿš€ Generate Animation", variant="primary", size="lg")
187
+
188
+ # ๊ฒฐ๊ณผ ์„น์…˜
189
+ gr.Markdown("## ๐Ÿ“ฝ๏ธ Results")
190
+ with gr.Row():
191
+ with gr.Column():
192
+ animation_output = gr.Video(
193
+ label="Animation Result",
194
+ elem_id="animation_output"
195
+ )
196
+ with gr.Column():
197
+ comparison_output = gr.Video(
198
+ label="Side-by-Side Comparison",
199
+ elem_id="comparison_output"
200
+ )
201
+
202
+ # ๋กœ๊ทธ ์„น์…˜
203
+ with gr.Accordion("๐Ÿ“‹ ์‹คํ–‰ ๋กœ๊ทธ", open=True):
204
+ logs_output = gr.Textbox(
205
+ label="Logs",
206
+ lines=10,
207
+ max_lines=20,
208
+ interactive=False,
209
+ elem_id="logs"
210
+ )
211
+
212
+ # ์˜ˆ์ œ ์„น์…˜
213
+ gr.Markdown("## ๐ŸŽฏ Examples")
214
+ gr.Examples(
215
+ examples=[
216
+ ["example_portrait.jpg", "example_audio.wav", 3.0, 10],
217
+ ["example_portrait2.jpg", "example_audio2.wav", 2.5, 15],
218
+ ],
219
+ inputs=[image_input, audio_input, guidance_scale, steps],
220
+ outputs=[animation_output, comparison_output, logs_output],
221
+ fn=generate_animation,
222
+ cache_examples=False
223
+ )
224
+
225
+ # ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ
226
+ check_connection_btn.click(
227
+ fn=test_api_connection,
228
+ outputs=[connection_status, connection_status]
229
+ )
230
+
231
+ generate_btn.click(
232
+ fn=generate_animation,
233
+ inputs=[image_input, audio_input, guidance_scale, steps],
234
+ outputs=[animation_output, comparison_output, logs_output]
235
+ )
236
+
237
+ # ํŽ˜์ด์ง€ ๋กœ๋“œ ์‹œ API ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ
238
+ demo.load(
239
+ fn=test_api_connection,
240
+ outputs=[connection_status, connection_status]
241
+ )
242
+
243
+ # ์•ฑ ์‹คํ–‰
244
+ if __name__ == "__main__":
245
+ demo.launch(
246
+ server_name="0.0.0.0",
247
+ server_port=7860,
248
+ share=False,
249
+ debug=True
250
+ )