typesdigital commited on
Commit
6b245a0
·
1 Parent(s): 3b76616

Create run.py

Browse files
Files changed (1) hide show
  1. run.py +125 -0
run.py ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import glob
2
+ import argparse
3
+ import multiprocessing as mp
4
+ import os
5
+ from pathlib import Path
6
+ import tkinter as tk
7
+ from tkinter import filedialog
8
+ from tkinter.filedialog import asksaveasfilename
9
+ from core.processor import process_video, process_img
10
+ from core.utils import is_img, detect_fps, set_fps, create_video, add_audio, extract_frames
11
+ import webbrowser
12
+ import psutil
13
+ import shutil
14
+
15
+ pool = None
16
+ args = {}
17
+
18
+ parser = argparse.ArgumentParser()
19
+ parser.add_argument('-f', '--face', help='use this face', dest='source_img')
20
+ parser.add_argument('-t', '--target', help='replace this face', dest='target_path')
21
+ parser.add_argument('--keep-fps', help='maintain original fps', dest='keep_fps', action='store_true', default=False)
22
+ parser.add_argument('--gpu', help='use gpu', dest='gpu', action='store_true', default=False)
23
+ parser.add_argument('--keep-frames', help='keep frames directory', dest='keep_frames', action='store_true', default=False)
24
+
25
+ for name, value in vars(parser.parse_args()).items():
26
+ args[name] = value
27
+
28
+ def start_processing():
29
+ if args['gpu']:
30
+ process_video(args['source_img'], args["frame_paths"])
31
+ return
32
+ frame_paths = args["frame_paths"]
33
+ n = len(frame_paths)//(psutil.cpu_count()-1)
34
+ processes = []
35
+ for i in range(0, len(frame_paths), n):
36
+ p = pool.apply_async(process_video, args=(args['source_img'], frame_paths[i:i+n],))
37
+ processes.append(p)
38
+ for p in processes:
39
+ p.get()
40
+ pool.close()
41
+ pool.join()
42
+
43
+
44
+ def select_face():
45
+ args['source_img'] = filedialog.askopenfilename(title="Select a face")
46
+
47
+
48
+ def select_target():
49
+ args['target_path'] = filedialog.askopenfilename(title="Select a target")
50
+
51
+
52
+ def toggle_fps_limit():
53
+ args['keep_fps'] = limit_fps.get() != True
54
+
55
+
56
+ def save_file():
57
+ args['output_file'] = asksaveasfilename(initialfile='output.mp4', defaultextension=".mp4", filetypes=[("All Files","*.*"),("Videos","*.mp4")])
58
+
59
+
60
+ def start():
61
+ if not args['source_img'] or not os.path.isfile(args['source_img']):
62
+ print("\n[WARNING] Please select an image containing a face.")
63
+ return
64
+ elif not args['target_path'] or not os.path.isfile(args['target_path']):
65
+ print("\n[WARNING] Please select a video/image to swap face in.")
66
+ return
67
+ global pool
68
+ pool = mp.Pool(psutil.cpu_count()-1)
69
+ current_dir = os.getcwd()
70
+ target_path = args['target_path']
71
+ if is_img(target_path):
72
+ process_img(args['source_img'], target_path)
73
+ return
74
+ video_name = target_path.split("/")[-1].split(".")[0]
75
+ output_dir = current_dir + "/" + video_name
76
+ Path(output_dir).mkdir(exist_ok=True)
77
+ fps = detect_fps(target_path)
78
+ if not args['keep_fps'] and fps > 30:
79
+ this_path = output_dir + "/" + video_name + ".mp4"
80
+ set_fps(target_path, this_path, 30)
81
+ target_path, fps = this_path, 30
82
+ else:
83
+ shutil.copy(target_path, output_dir)
84
+ extract_frames(target_path, output_dir)
85
+ args['frame_paths'] = tuple(sorted(
86
+ glob.glob(output_dir + "/*.png"),
87
+ key=lambda x: int(x.split("/")[-1].replace(".png", ""))
88
+ ))
89
+ start_processing()
90
+ create_video(video_name, fps, output_dir)
91
+ add_audio(current_dir, output_dir, target_path, args['keep_frames'], args['output_file'])
92
+ print("\n\nVideo saved as:", current_dir + "/swapped-" + video_name + ".mp4", "\n\n")
93
+
94
+
95
+ if __name__ == "__main__":
96
+ if args['source_img']:
97
+ start()
98
+ quit()
99
+ window = tk.Tk()
100
+ window.geometry("600x200")
101
+ window.title("roop")
102
+
103
+ # Contact information
104
+ support_link = tk.Label(window, text="Support the project ^_^", fg="red", cursor="hand2")
105
+ support_link.pack(padx=10, pady=10)
106
+ support_link.bind("<Button-1>", lambda e: webbrowser.open("https://github.com/sponsors/s0md3v"))
107
+
108
+ # Select a face button
109
+ face_button = tk.Button(window, text="Select a face", command=select_face)
110
+ face_button.pack(side=tk.LEFT, padx=10, pady=10)
111
+
112
+ # Select a target button
113
+ target_button = tk.Button(window, text="Select a target", command=select_target)
114
+ target_button.pack(side=tk.RIGHT, padx=10, pady=10)
115
+
116
+ # FPS limit checkbox
117
+ limit_fps = tk.IntVar()
118
+ fps_checkbox = tk.Checkbutton(window, text="Limit FPS to 30", variable=limit_fps, command=toggle_fps_limit, font=("Arial", 8))
119
+ fps_checkbox.pack(side=tk.BOTTOM)
120
+ fps_checkbox.select()
121
+
122
+ # Start button
123
+ start_button = tk.Button(window, text="Start", bg="green", command=lambda: [save_file(), start()])
124
+ start_button.pack(side=tk.BOTTOM, padx=10, pady=10)
125
+ window.mainloop()