Profakerr commited on
Commit
0408575
1 Parent(s): eaa25ba

Upload 2 files

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