openfree commited on
Commit
7bf073b
·
verified ·
1 Parent(s): 4c14d3a

Create app-backup.py

Browse files
Files changed (1) hide show
  1. app-backup.py +193 -0
app-backup.py ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import spaces
2
+ import gradio as gr
3
+ import os
4
+ import numpy as np
5
+ from pydub import AudioSegment
6
+ import hashlib
7
+ from sonic import Sonic
8
+ from PIL import Image
9
+ import torch
10
+
11
+ # 모델 초기화
12
+ cmd = (
13
+ 'python3 -m pip install "huggingface_hub[cli]"; '
14
+ 'huggingface-cli download LeonJoe13/Sonic --local-dir checkpoints; '
15
+ 'huggingface-cli download stabilityai/stable-video-diffusion-img2vid-xt --local-dir checkpoints/stable-video-diffusion-img2vid-xt; '
16
+ 'huggingface-cli download openai/whisper-tiny --local-dir checkpoints/whisper-tiny;'
17
+ )
18
+ os.system(cmd)
19
+
20
+ pipe = Sonic()
21
+
22
+ def get_md5(content):
23
+ md5hash = hashlib.md5(content)
24
+ return md5hash.hexdigest()
25
+
26
+ @spaces.GPU(duration=300) # 긴 비디오 처리를 위해 duration 300초로 설정
27
+ def get_video_res(img_path, audio_path, res_video_path, dynamic_scale=1.0):
28
+ expand_ratio = 0.5
29
+ min_resolution = 512
30
+ inference_steps = 25 # 2초 분량의 비디오(25 프레임)로 고정
31
+
32
+ # 오디오 길이(참고용) 출력
33
+ audio = AudioSegment.from_file(audio_path)
34
+ duration = len(audio) / 1000.0 # 초 단위
35
+ print(f"Audio duration: {duration} seconds, using inference_steps: {inference_steps}")
36
+
37
+ face_info = pipe.preprocess(img_path, expand_ratio=expand_ratio)
38
+ print(f"Face detection info: {face_info}")
39
+
40
+ if face_info['face_num'] > 0:
41
+ crop_image_path = img_path + '.crop.png'
42
+ pipe.crop_image(img_path, crop_image_path, face_info['crop_bbox'])
43
+ img_path = crop_image_path
44
+ os.makedirs(os.path.dirname(res_video_path), exist_ok=True)
45
+
46
+ # 고정된 inference_steps(25)로 비디오 생성
47
+ pipe.process(
48
+ img_path,
49
+ audio_path,
50
+ res_video_path,
51
+ min_resolution=min_resolution,
52
+ inference_steps=inference_steps,
53
+ dynamic_scale=dynamic_scale
54
+ )
55
+ return res_video_path
56
+ else:
57
+ return -1
58
+
59
+ tmp_path = './tmp_path/'
60
+ res_path = './res_path/'
61
+ os.makedirs(tmp_path, exist_ok=True)
62
+ os.makedirs(res_path, exist_ok=True)
63
+
64
+ def process_sonic(image, audio, dynamic_scale):
65
+ # 입력 검증
66
+ if image is None:
67
+ raise gr.Error("Please upload an image")
68
+ if audio is None:
69
+ raise gr.Error("Please upload an audio file")
70
+
71
+ img_md5 = get_md5(np.array(image))
72
+ audio_md5 = get_md5(audio[1])
73
+ print(f"Processing with image hash: {img_md5}, audio hash: {audio_md5}")
74
+
75
+ sampling_rate, arr = audio[:2]
76
+ if len(arr.shape) == 1:
77
+ arr = arr[:, None]
78
+
79
+ # numpy array로부터 AudioSegment 생성
80
+ audio_segment = AudioSegment(
81
+ arr.tobytes(),
82
+ frame_rate=sampling_rate,
83
+ sample_width=arr.dtype.itemsize,
84
+ channels=arr.shape[1]
85
+ )
86
+ audio_segment = audio_segment.set_frame_rate(sampling_rate)
87
+
88
+ # 파일 경로 생성
89
+ image_path = os.path.abspath(os.path.join(tmp_path, f'{img_md5}.png'))
90
+ audio_path = os.path.abspath(os.path.join(tmp_path, f'{audio_md5}.wav'))
91
+ res_video_path = os.path.abspath(os.path.join(res_path, f'{img_md5}_{audio_md5}_{dynamic_scale}.mp4'))
92
+
93
+ # 입력 파일이 없으면 저장
94
+ if not os.path.exists(image_path):
95
+ image.save(image_path)
96
+ if not os.path.exists(audio_path):
97
+ audio_segment.export(audio_path, format="wav")
98
+
99
+ # 캐시된 결과가 있으면 반환, 없으면 새로 생성
100
+ if os.path.exists(res_video_path):
101
+ print(f"Using cached result: {res_video_path}")
102
+ return res_video_path
103
+ else:
104
+ print(f"Generating new video with dynamic scale: {dynamic_scale}")
105
+ return get_video_res(image_path, audio_path, res_video_path, dynamic_scale)
106
+
107
+ # 예시 데이터를 위한 dummy 함수 (필요시 실제 예시 데이터를 추가하세요)
108
+ def get_example():
109
+ return []
110
+
111
+ css = """
112
+ .gradio-container {
113
+ font-family: 'Arial', sans-serif;
114
+ }
115
+ .main-header {
116
+ text-align: center;
117
+ color: #2a2a2a;
118
+ margin-bottom: 2em;
119
+ }
120
+ .parameter-section {
121
+ background-color: #f5f5f5;
122
+ padding: 1em;
123
+ border-radius: 8px;
124
+ margin: 1em 0;
125
+ }
126
+ .example-section {
127
+ margin-top: 2em;
128
+ }
129
+ """
130
+
131
+ with gr.Blocks(css=css,theme="apriel") as demo:
132
+ gr.HTML("""
133
+ <div class="main-header">
134
+ <h1>🎭 Sonic: Advanced Portrait Animation</h1>
135
+ <p>Transform still images into dynamic videos synchronized with audio</p>
136
+ </div>
137
+ """)
138
+
139
+ with gr.Row():
140
+ with gr.Column():
141
+ image_input = gr.Image(
142
+ type='pil',
143
+ label="Portrait Image",
144
+ elem_id="image_input"
145
+ )
146
+
147
+ audio_input = gr.Audio(
148
+ label="Voice/Audio Input",
149
+ elem_id="audio_input",
150
+ type="numpy"
151
+ )
152
+
153
+ with gr.Column():
154
+ dynamic_scale = gr.Slider(
155
+ minimum=0.5,
156
+ maximum=2.0,
157
+ value=1.0,
158
+ step=0.1,
159
+ label="Animation Intensity",
160
+ info="Adjust to control movement intensity (0.5: subtle, 2.0: dramatic)"
161
+ )
162
+
163
+ process_btn = gr.Button(
164
+ "Generate Animation",
165
+ variant="primary",
166
+ elem_id="process_btn"
167
+ )
168
+
169
+ with gr.Column():
170
+ video_output = gr.Video(
171
+ label="Generated Animation",
172
+ elem_id="video_output"
173
+ )
174
+
175
+ process_btn.click(
176
+ fn=process_sonic,
177
+ inputs=[image_input, audio_input, dynamic_scale],
178
+ outputs=video_output,
179
+ api_name="animate"
180
+ )
181
+
182
+ gr.Examples(
183
+ examples=get_example(),
184
+ fn=process_sonic,
185
+ inputs=[image_input, audio_input, dynamic_scale],
186
+ outputs=video_output,
187
+ cache_examples=False
188
+ )
189
+
190
+
191
+
192
+ # 공개 링크 생성: share=True
193
+ demo.launch(share=True)