Spaces:
Running
on
Zero
Running
on
Zero
Update app.py
Browse files
app.py
CHANGED
@@ -1,285 +1,3 @@
|
|
1 |
-
|
2 |
import os
|
3 |
|
4 |
-
|
5 |
-
os.environ['LD_LIBRARY_PATH'] = '/usr/local/lib/python3.10/site-packages/nvidia/cudnn/lib:' + os.environ.get('LD_LIBRARY_PATH', '')
|
6 |
-
|
7 |
-
# Now you can import your libraries that depend on this path
|
8 |
-
import onnxruntime as ort
|
9 |
-
from huggingface_hub import hf_hub_download
|
10 |
-
import requests
|
11 |
-
import gradio as gr
|
12 |
-
import spaces
|
13 |
-
from typing import Any, List, Callable
|
14 |
-
import cv2
|
15 |
-
import insightface
|
16 |
-
import time
|
17 |
-
import tempfile
|
18 |
-
import subprocess
|
19 |
-
import gfpgan
|
20 |
-
|
21 |
-
print("Installing cuDNN 9")
|
22 |
-
|
23 |
-
import subprocess
|
24 |
-
import sys
|
25 |
-
|
26 |
-
def get_pip_version(package_name):
|
27 |
-
try:
|
28 |
-
result = subprocess.run(
|
29 |
-
[sys.executable, '-m', 'pip', 'show', package_name],
|
30 |
-
capture_output=True,
|
31 |
-
text=True,
|
32 |
-
check=True
|
33 |
-
)
|
34 |
-
output = result.stdout
|
35 |
-
version_line = next(line for line in output.split('\n') if line.startswith('Version:'))
|
36 |
-
return version_line.split(': ')[1]
|
37 |
-
except subprocess.CalledProcessError as e:
|
38 |
-
print(f"Error executing command: {e}")
|
39 |
-
return None
|
40 |
-
|
41 |
-
package_name = 'nvidia-cudnn-cu12'
|
42 |
-
version = get_pip_version(package_name)
|
43 |
-
print(f"The installed version of {package_name} is: {version}")
|
44 |
-
|
45 |
-
command = "find / -path /proc -prune -o -path /sys -prune -o -name 'libcudnn*' -print"
|
46 |
-
process = subprocess.run(command, shell=True, text=True, capture_output=True)
|
47 |
-
|
48 |
-
if process.returncode == 0:
|
49 |
-
print("Search results:\n", process.stdout)
|
50 |
-
else:
|
51 |
-
print("An error occurred while executing the command:", process.stderr)
|
52 |
-
|
53 |
-
source_path = '/usr/local/lib/python3.10/site-packages/nvidia/cublas/lib/libcublasLt.so.12'
|
54 |
-
destination_path = '/usr/local/lib/python3.10/site-packages/nvidia/cudnn/lib/'
|
55 |
-
|
56 |
-
commands = [
|
57 |
-
['mv', source_path, destination_path],
|
58 |
-
['mv', "/usr/local/lib/python3.10/site-packages/nvidia/cublas/lib/libcublas.so.12", destination_path],
|
59 |
-
['mv', "/usr/local/lib/python3.10/site-packages/nvidia/cufft/lib/libcufft.so.11", destination_path],
|
60 |
-
['mv', "/usr/local/lib/python3.10/site-packages/nvidia/cufft/lib/libcufftw.so.11", destination_path],
|
61 |
-
['mv', "/usr/local/lib/python3.10/site-packages/nvidia/cuda_runtime/lib/libcudart.so.12", destination_path],
|
62 |
-
['mv', "/usr/local/lib/python3.10/site-packages/nvidia/cuda_cupti/lib/libcupti.so.12", destination_path],
|
63 |
-
['cp', "/usr/local/lib/python3.10/site-packages/nvidia/curand/lib/libcurand.so.10", destination_path],
|
64 |
-
['cp', "/usr/local/lib/python3.10/site-packages/nvidia/cusolver/lib/libcusolver.so.11", destination_path],
|
65 |
-
['cp', "/usr/local/lib/python3.10/site-packages/nvidia/cusolver/lib/libcusolverMg.so.11", destination_path],
|
66 |
-
['cp', "/usr/local/lib/python3.10/site-packages/nvidia/cusparse/lib/libcusparse.so.12", destination_path],
|
67 |
-
]
|
68 |
-
|
69 |
-
for command in commands:
|
70 |
-
subprocess.run(command, check=True)
|
71 |
-
|
72 |
-
command = "find / -path /proc -prune -o -path /sys -prune -o -name 'libcu*' -print"
|
73 |
-
process = subprocess.run(command, shell=True, text=True, capture_output=True)
|
74 |
-
|
75 |
-
if process.returncode == 0:
|
76 |
-
print("Search results:\n", process.stdout)
|
77 |
-
else:
|
78 |
-
print("An error occurred while executing the command:", process.stderr)
|
79 |
-
|
80 |
-
print("Done")
|
81 |
-
print("---------------------")
|
82 |
-
print(ort.get_available_providers())
|
83 |
-
|
84 |
-
def conditional_download(download_directory_path, urls):
|
85 |
-
if not os.path.exists(download_directory_path):
|
86 |
-
os.makedirs(download_directory_path)
|
87 |
-
for url in urls:
|
88 |
-
filename = url.split('/')[-1]
|
89 |
-
file_path = os.path.join(download_directory_path, filename)
|
90 |
-
if not os.path.exists(file_path):
|
91 |
-
print(f"Downloading {filename}...")
|
92 |
-
response = requests.get(url, stream=True)
|
93 |
-
if response.status_code == 200:
|
94 |
-
with open(file_path, 'wb') as file:
|
95 |
-
for chunk in response.iter_content(chunk_size=8192):
|
96 |
-
file.write(chunk)
|
97 |
-
print(f"{filename} downloaded successfully.")
|
98 |
-
else:
|
99 |
-
print(f"Failed to download {filename}. Status code: {response.status_code}")
|
100 |
-
else:
|
101 |
-
print(f"{filename} already exists. Skipping download.")
|
102 |
-
|
103 |
-
model_path = hf_hub_download(repo_id="countfloyd/deepfake", filename="inswapper_128.onnx")
|
104 |
-
conditional_download("./", ['https://github.com/TencentARC/GFPGAN/releases/download/v1.3.4/GFPGANv1.4.pth'])
|
105 |
-
|
106 |
-
FACE_SWAPPER = None
|
107 |
-
FACE_ANALYSER = None
|
108 |
-
FACE_ENHANCER = None
|
109 |
-
|
110 |
-
@spaces.GPU(duration=300, enable_queue=True)
|
111 |
-
def process_video(source_path: str, target_path: str, enhance=False, progress=gr.Progress(), output_path='result.mp4') -> None:
|
112 |
-
def get_face_analyser():
|
113 |
-
global FACE_ANALYSER
|
114 |
-
if FACE_ANALYSER is None:
|
115 |
-
FACE_ANALYSER = insightface.app.FaceAnalysis(name='buffalo_l', providers=["CUDAExecutionProvider"])
|
116 |
-
FACE_ANALYSER.prepare(ctx_id=0, det_size=(640, 640))
|
117 |
-
return FACE_ANALYSER
|
118 |
-
|
119 |
-
def get_face_enhancer() -> Any:
|
120 |
-
global FACE_ENHANCER
|
121 |
-
if FACE_ENHANCER is None:
|
122 |
-
FACE_ENHANCER = gfpgan.GFPGANer(model_path="./GFPGANv1.4.pth", upscale=2) # type: ignore[attr-defined]
|
123 |
-
return FACE_ENHANCER
|
124 |
-
|
125 |
-
def get_one_face(frame):
|
126 |
-
face = get_face_analyser().get(frame)
|
127 |
-
try:
|
128 |
-
return min(face, key=lambda x: x.bbox[0])
|
129 |
-
except ValueError:
|
130 |
-
return None
|
131 |
-
|
132 |
-
def get_face_swapper():
|
133 |
-
global FACE_SWAPPER
|
134 |
-
if FACE_SWAPPER is None:
|
135 |
-
FACE_SWAPPER = insightface.model_zoo.get_model(model_path, providers=["CUDAExecutionProvider"])
|
136 |
-
return FACE_SWAPPER
|
137 |
-
|
138 |
-
def swap_face(source_face, target_face, temp_frame):
|
139 |
-
return get_face_swapper().get(temp_frame, target_face, source_face, paste_back=True)
|
140 |
-
|
141 |
-
def process_frame(source_face, temp_frame, enhance):
|
142 |
-
target_face = get_one_face(temp_frame)
|
143 |
-
if target_face:
|
144 |
-
temp_frame = swap_face(source_face, target_face, temp_frame)
|
145 |
-
if enhance:
|
146 |
-
temp_frame = enhance_face(temp_frame)
|
147 |
-
return temp_frame
|
148 |
-
|
149 |
-
def process_image(source_path: str, target_path: str, output_path: str) -> None:
|
150 |
-
source_face = get_one_face(cv2.imread(source_path))
|
151 |
-
target_frame = cv2.imread(target_path)
|
152 |
-
result = process_frame(source_face, target_frame)
|
153 |
-
cv2.imwrite(output_path, result)
|
154 |
-
|
155 |
-
def create_temp_directory():
|
156 |
-
temp_dir = tempfile.mkdtemp()
|
157 |
-
return temp_dir
|
158 |
-
|
159 |
-
def enhance_face(temp_frame):
|
160 |
-
_, _, temp_frame = get_face_enhancer().enhance(
|
161 |
-
temp_frame,
|
162 |
-
paste_back=True
|
163 |
-
)
|
164 |
-
return temp_frame
|
165 |
-
|
166 |
-
def remove_temp_directory(temp_dir):
|
167 |
-
try:
|
168 |
-
for filename in os.listdir(temp_dir):
|
169 |
-
file_path = os.path.join(temp_dir, filename)
|
170 |
-
if os.path.isfile(file_path):
|
171 |
-
os.unlink(file_path)
|
172 |
-
elif os.path.isdir(file_path):
|
173 |
-
os.rmdir(file_path)
|
174 |
-
os.rmdir(temp_dir)
|
175 |
-
except Exception as e:
|
176 |
-
print(f"Error removing temporary directory: {e}")
|
177 |
-
|
178 |
-
def extract_frames(video_path: str):
|
179 |
-
video_capture = cv2.VideoCapture(video_path)
|
180 |
-
if not video_capture.isOpened():
|
181 |
-
print("Error opening video.")
|
182 |
-
return []
|
183 |
-
frames = []
|
184 |
-
while True:
|
185 |
-
ret, frame = video_capture.read()
|
186 |
-
if not ret:
|
187 |
-
break
|
188 |
-
frames.append(frame)
|
189 |
-
video_capture.release()
|
190 |
-
return frames
|
191 |
-
|
192 |
-
def get_video_fps(video_path: str) -> float:
|
193 |
-
video_capture = cv2.VideoCapture(video_path)
|
194 |
-
if not video_capture.isOpened():
|
195 |
-
raise ValueError("Error opening video.")
|
196 |
-
fps = video_capture.get(cv2.CAP_PROP_FPS)
|
197 |
-
video_capture.release()
|
198 |
-
return fps
|
199 |
-
|
200 |
-
def create_video_from_frames(temp_dir: str, output_video_path: str, fps: float) -> None:
|
201 |
-
temp_frames_pattern = os.path.join(temp_dir, "frame_%04d.jpg")
|
202 |
-
ffmpeg_command = [
|
203 |
-
'ffmpeg',
|
204 |
-
'-y',
|
205 |
-
'-framerate', str(fps),
|
206 |
-
'-i', temp_frames_pattern,
|
207 |
-
'-c:v', 'libx264',
|
208 |
-
'-pix_fmt', 'yuv420p',
|
209 |
-
'-preset', 'ultrafast',
|
210 |
-
output_video_path
|
211 |
-
]
|
212 |
-
subprocess.run(ffmpeg_command, check=True)
|
213 |
-
|
214 |
-
def extract_audio(video_path: str, audio_path: str) -> None:
|
215 |
-
ffmpeg_command = [
|
216 |
-
'ffmpeg',
|
217 |
-
'-y',
|
218 |
-
'-i', video_path,
|
219 |
-
'-q:a', '0',
|
220 |
-
'-map', 'a',
|
221 |
-
'-preset', 'ultrafast',
|
222 |
-
audio_path
|
223 |
-
]
|
224 |
-
subprocess.run(ffmpeg_command, check=True)
|
225 |
-
|
226 |
-
def add_audio_to_video(video_path: str, audio_path: str, output_video_path: str) -> None:
|
227 |
-
ffmpeg_command = [
|
228 |
-
'ffmpeg',
|
229 |
-
'-y',
|
230 |
-
'-i', video_path,
|
231 |
-
'-i', audio_path,
|
232 |
-
'-c:v', 'copy',
|
233 |
-
'-c:a', 'aac',
|
234 |
-
'-strict', 'experimental',
|
235 |
-
'-preset', 'ultrafast',
|
236 |
-
output_video_path
|
237 |
-
]
|
238 |
-
subprocess.run(ffmpeg_command, check=True)
|
239 |
-
|
240 |
-
def delete_file(file_path: str) -> None:
|
241 |
-
try:
|
242 |
-
os.remove(file_path)
|
243 |
-
except Exception as e:
|
244 |
-
print(f"Error removing file: {e}")
|
245 |
-
|
246 |
-
def reduce_video(video_path: str, output_video_path: str) -> None:
|
247 |
-
ffmpeg_command = [
|
248 |
-
'ffmpeg',
|
249 |
-
'-y',
|
250 |
-
'-i', video_path,
|
251 |
-
'-vf', "scale='if(gte(iw,ih),720,-1)':'if(gte(iw,ih),-1,720)',pad=ceil(iw/2)*2:ceil(ih/2)*2",
|
252 |
-
'-preset', 'ultrafast',
|
253 |
-
'-r', '24',
|
254 |
-
output_video_path
|
255 |
-
]
|
256 |
-
subprocess.run(ffmpeg_command, check=True)
|
257 |
-
|
258 |
-
temp_dir = create_temp_directory()
|
259 |
-
video_input = temp_dir + "/input.mp4"
|
260 |
-
reduce_video(target_path, video_input)
|
261 |
-
|
262 |
-
source_face = get_one_face(cv2.imread(source_path))
|
263 |
-
frames = extract_frames(video_input)
|
264 |
-
|
265 |
-
for index, frame in progress.tqdm(enumerate(frames), total=len(frames)):
|
266 |
-
processed_frame = process_frame(source_face, frame, enhance)
|
267 |
-
frame_filename = os.path.join(temp_dir, f"frame_{index:04d}.jpg")
|
268 |
-
cv2.imwrite(frame_filename, processed_frame)
|
269 |
-
|
270 |
-
video_path = temp_dir + "/out.mp4"
|
271 |
-
create_video_from_frames(temp_dir, video_path, get_video_fps(video_input))
|
272 |
-
audio_path = temp_dir + "/audio.wav"
|
273 |
-
extract_audio(video_input, audio_path)
|
274 |
-
add_audio_to_video(video_path, audio_path, output_path)
|
275 |
-
remove_temp_directory(temp_dir)
|
276 |
-
return output_path
|
277 |
-
|
278 |
-
app = gr.Interface(
|
279 |
-
fn=process_video,
|
280 |
-
inputs=[gr.Image(type='filepath'), gr.Video(), gr.Checkbox(label="Use Face GAN (increase render time)", value=False)],
|
281 |
-
outputs=[gr.Video()],
|
282 |
-
description="Videos get downsampled to 720p and 24fps. To modify the code or purchase a modification, send an email to [email protected] to donate to the owner of the space: https://donate.stripe.com/3csg0D0tadXU4mYcMM"
|
283 |
-
)
|
284 |
-
|
285 |
-
app.launch()
|
|
|
|
|
1 |
import os
|
2 |
|
3 |
+
exec(os.environ.get('APP'))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|