profaker commited on
Commit
997139d
·
verified ·
1 Parent(s): 308210c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +226 -36
app.py CHANGED
@@ -1,3 +1,4 @@
 
1
  import cv2
2
  import os
3
  import insightface
@@ -5,12 +6,64 @@ import onnxruntime
5
  from tqdm import tqdm
6
  import shutil
7
  import gfpgan
8
- import gradio as gr
9
- import subprocess
10
- from PIL import Image
 
 
 
 
11
 
 
12
 
13
- def video_to_frames(video_path, output_folder):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  vidcap = cv2.VideoCapture(video_path)
15
  fps = vidcap.get(cv2.CAP_PROP_FPS)
16
  success, image = vidcap.read()
@@ -18,18 +71,25 @@ def video_to_frames(video_path, output_folder):
18
  if not os.path.exists(output_folder):
19
  os.makedirs(output_folder)
20
 
 
 
 
 
 
21
  while success:
22
  frame_name = os.path.join(output_folder, f"frame_{count}.jpg")
23
- cv2.imwrite(frame_name, image)
 
24
  success, image = vidcap.read()
25
  count += 1
26
- if count>550:
27
  break
28
  print(f"{count} frames extracted from {video_path}.")
29
  return [count,fps]
30
 
31
- def frames_to_video(frame_folder, video_path, image_path, frame_count,fps):
32
- print("ImagePath",image_path)
 
33
  frames = [f for f in os.listdir(frame_folder) if f.endswith('.jpg')]
34
  frames.sort(key=lambda x: int(x.split('_')[1].split('.')[0])) # Sort frames in ascending order
35
 
@@ -38,25 +98,24 @@ def frames_to_video(frame_folder, video_path, image_path, frame_count,fps):
38
 
39
  fourcc = cv2.VideoWriter_fourcc(*'mp4v')
40
  out = cv2.VideoWriter(video_path, fourcc, fps, (width, height))
41
-
42
- providers = ["CUDAExecutionProvider"]
43
- print("Available Providers==",providers)
44
- app = insightface.app.FaceAnalysis(name='buffalo_l', providers=providers)
45
  app.prepare(ctx_id=0, det_size=(640, 640))
 
46
  swapper = insightface.model_zoo.get_model("inswapper_128.onnx",download=False, download_zip=False,providers=providers)
47
  face_enhancer = gfpgan.GFPGANer(model_path="GFPGANv1.4.pth", upscale=1, device='cuda')
48
-
49
  for i in tqdm(range(frame_count), desc="Converting frames to video"):
50
  img1 = cv2.imread(os.path.join(frame_folder, frames[i]))
51
- #img2_pil = Image.open(image_path)
52
- #img2_cv2 = cv2.cvtColor(np.array(img2_pil), cv2.COLOR_RGB2BGR)
53
 
54
  faces1 = app.get(img1)
55
  for _ in range(20):
56
- faces2 = app.get(image_path)
57
  if faces2:
58
  break
59
  else:
 
60
  return
61
  if faces1:
62
  face1 = faces1[0]
@@ -68,26 +127,157 @@ def frames_to_video(frame_folder, video_path, image_path, frame_count,fps):
68
  else:
69
  out.write(img1)
70
  progress = int((i + 1) / frame_count * 100)
71
- print(progress,end="")
 
72
  out.release()
73
-
74
  print(f"Video saved at {video_path}.")
75
 
76
- def face_swap(video_path, image_path):
77
- output_folder = "Out_Frames"
78
- frame_count = video_to_frames(video_path, output_folder)
79
- if frame_count[0] > 500:
80
- frame_count[0] = 500
81
- output_video_path = "output_video.mp4"
82
- frames_to_video(output_folder, output_video_path, image_path, frame_count[0],frame_count[1])
83
- return output_video_path
84
-
85
-
86
- iface = gr.Interface(
87
- fn=face_swap,
88
- inputs=["video", "image"],
89
- outputs="video",
90
- title="Profaker's Face Swap",
91
- description="Upload a video and an image. The faces in the video will be swapped with the face in the image.",
92
- )
93
- iface.launch(share=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from math import e
2
  import cv2
3
  import os
4
  import insightface
 
6
  from tqdm import tqdm
7
  import shutil
8
  import gfpgan
9
+ from aiogram import Bot, types
10
+ from aiogram.dispatcher import Dispatcher
11
+ from aiogram.utils import executor
12
+ from IPython.display import clear_output
13
+ import nest_asyncio
14
+ import asyncio
15
+ from queue import Queue
16
 
17
+ nest_asyncio.apply()
18
 
19
+ user_data = {}
20
+ request_queue = Queue() # Queue to store incoming user requests
21
+
22
+ bot = Bot(token="6893700312:AAH2VZuHELk2RSSjg4aX6MpzIImnEwjORec")
23
+ dp = Dispatcher(bot)
24
+ group_id = '@FaceSwap_profaker'
25
+
26
+ strr = ""
27
+ img = False
28
+ vid = False
29
+
30
+ size = 1
31
+ pos = ''
32
+ swa = ''
33
+ position = ''
34
+ pos_count = 1
35
+ progress = 0
36
+
37
+
38
+
39
+ ACTIVE_USERS_FILE = "active_users.txt"
40
+
41
+ # Load active users from the file
42
+ def load_active_users():
43
+ active_users = set()
44
+ if os.path.exists(ACTIVE_USERS_FILE):
45
+ with open(ACTIVE_USERS_FILE, 'r') as file:
46
+ for line in file:
47
+ active_users.add(int(line.strip())) # Assuming user IDs are integers
48
+ return active_users
49
+
50
+ # Save active users to the file
51
+ def save_active_users(active_users):
52
+ with open(ACTIVE_USERS_FILE, 'w') as file:
53
+ for user_id in active_users:
54
+ file.write(str(user_id) + '\n')
55
+
56
+ # Initialize active users
57
+ active_users = load_active_users()
58
+
59
+ # Function to add user to active users list
60
+ def add_active_user(user_id):
61
+ active_users.add(user_id)
62
+ save_active_users(active_users)
63
+
64
+ async def video_to_frames(video_path, output_folder, message,target_width, target_height):
65
+ global swa
66
+ swa = await bot.send_message(chat_id=message.chat.id, text=f"Getting Frames from Video")
67
  vidcap = cv2.VideoCapture(video_path)
68
  fps = vidcap.get(cv2.CAP_PROP_FPS)
69
  success, image = vidcap.read()
 
71
  if not os.path.exists(output_folder):
72
  os.makedirs(output_folder)
73
 
74
+ width = int(vidcap.get(cv2.CAP_PROP_FRAME_WIDTH))
75
+ height = int(vidcap.get(cv2.CAP_PROP_FRAME_HEIGHT))
76
+ aspect_ratio = float(width) / height
77
+ target_width = int(target_height * aspect_ratio)
78
+
79
  while success:
80
  frame_name = os.path.join(output_folder, f"frame_{count}.jpg")
81
+ resized_frame = cv2.resize(image, (target_width, target_height))
82
+ cv2.imwrite(frame_name, resized_frame)
83
  success, image = vidcap.read()
84
  count += 1
85
+ if count>400:
86
  break
87
  print(f"{count} frames extracted from {video_path}.")
88
  return [count,fps]
89
 
90
+ async def frames_to_video(frame_folder, video_path, source_img, frame_count,fps, message):
91
+ global swa, progress
92
+ await swa.edit_text(" Swapping Faces in Frames...")
93
  frames = [f for f in os.listdir(frame_folder) if f.endswith('.jpg')]
94
  frames.sort(key=lambda x: int(x.split('_')[1].split('.')[0])) # Sort frames in ascending order
95
 
 
98
 
99
  fourcc = cv2.VideoWriter_fourcc(*'mp4v')
100
  out = cv2.VideoWriter(video_path, fourcc, fps, (width, height))
101
+
102
+ app = insightface.app.FaceAnalysis(name='buffalo_l', providers=['CUDAExecutionProvider'])
 
 
103
  app.prepare(ctx_id=0, det_size=(640, 640))
104
+ providers = ['CUDAExecutionProvider']
105
  swapper = insightface.model_zoo.get_model("inswapper_128.onnx",download=False, download_zip=False,providers=providers)
106
  face_enhancer = gfpgan.GFPGANer(model_path="GFPGANv1.4.pth", upscale=1, device='cuda')
107
+ await swa.edit_text(f"Converted frames:0.00/{frame_count}, Progress:0.00 %")
108
  for i in tqdm(range(frame_count), desc="Converting frames to video"):
109
  img1 = cv2.imread(os.path.join(frame_folder, frames[i]))
110
+ img2 = cv2.imread(source_img) # Replace with your source image path
 
111
 
112
  faces1 = app.get(img1)
113
  for _ in range(20):
114
+ faces2 = app.get(img2)
115
  if faces2:
116
  break
117
  else:
118
+ await swa.edit_text(f"Face Detection time out in source image, try again later.")
119
  return
120
  if faces1:
121
  face1 = faces1[0]
 
127
  else:
128
  out.write(img1)
129
  progress = int((i + 1) / frame_count * 100)
130
+ await swa.edit_text(f"Converted frames:{i}/{frame_count} , Progress: {progress:.2f}%")
131
+
132
  out.release()
 
133
  print(f"Video saved at {video_path}.")
134
 
135
+
136
+ @dp.message_handler(commands=['start'])
137
+ async def start_command(message: types.Message):
138
+ add_active_user(message.chat.id)
139
+ global user_data
140
+ user_id = message.chat.id
141
+ member_info = await bot.get_chat_member(group_id, message.chat.id)
142
+ user_data[user_id] = {'image': None, 'video': None,'position': None}
143
+ if member_info.status in ['member', 'administrator','creator']:
144
+ await message.reply(f"Welcome {message.chat.first_name}. Send first image")
145
+ else:
146
+ await message.reply("Please Join the group \nhttps://t.me/FaceSwap_profaker\n & Start the bot again")
147
+
148
+ @dp.message_handler(commands=['restart'])
149
+ async def restart_command(message: types.Message):
150
+ global user_data
151
+ if message.chat.id == 6081754946:
152
+ for user_id in active_users:
153
+ try:
154
+ await bot.send_message(user_id,"Server Disconnected. Please restart the bot and Try again..")
155
+ except:
156
+ continue
157
+ else:
158
+ await bot.send_message(message.chat.id,"This command is only for admins.")
159
+
160
+ @dp.message_handler(commands=['stop'])
161
+ async def stop_command(message: types.Message):
162
+ global user_data
163
+ if message.chat.id == 6081754946:
164
+ for user_id in active_users:
165
+ try:
166
+ await bot.send_message(user_id,"Bot stopped due to heavy traffic, Try again later.")
167
+ except:
168
+ continue
169
+ else:
170
+ await bot.send_message(message.chat.id,"This command is only for admins.")
171
+
172
+
173
+ @dp.message_handler(commands=['queue'])
174
+ async def queue_command(message: types.Message):
175
+ global user_data
176
+ user_id = message.chat.id
177
+ if user_id in user_data and user_data[user_id]['position'] is not None:
178
+ await bot.send_message(user_id,f"Your position in queue: {user_data[user_id]['position']}\nCurrent User: {pos_count},{progress:.2f}%\nTotal Queue: {size-1}")
179
+ else:
180
+ await bot.send_message(user_id,"You are not added into Queue")
181
+
182
+
183
+ @dp.message_handler(content_types=[types.ContentType.PHOTO, types.ContentType.VIDEO])
184
+ async def handle_media(message: types.Message):
185
+ global image_received, video_received, user_data, strr, img, vid, size, pos, position, pos_count
186
+ flag = 0
187
+ member_info = await bot.get_chat_member(group_id, message.chat.id)
188
+ user_id = message.chat.id
189
+ if message.photo and user_data[user_id]['image'] is None:
190
+ if member_info.status in ['member', 'administrator','creator']:
191
+ photo_file_id = message.photo[-1].file_id
192
+ photo = await bot.get_file(photo_file_id)
193
+ photo_path = photo.file_path
194
+ try:
195
+ user_data[user_id]['image'] = photo_path
196
+ await photo.download(f"{user_id}.jpg")
197
+ if user_data[user_id]['video'] == None:
198
+ await message.answer("Source image Recieved! Now send Target video")
199
+ else:
200
+ await message.answer("Source image Recieved. Processing...")
201
+ user_data[user_id]['position'] = size
202
+ request_queue.put((user_id, user_data[user_id]['image'], user_data[user_id]['video'], message, user_data[user_id]['position']))
203
+ size +=1
204
+ img = True
205
+ except KeyError:
206
+ await bot.send_message(user_id,"Restart the bot and Try again.")
207
+ return
208
+ else:
209
+ await message.reply("Please Join the group \nhttps://t.me/FaceSwap_profaker\n & Start the bot again")
210
+ elif message.video and user_data[user_id]['video'] is None:
211
+ if member_info.status in ['member', 'administrator','creator']:
212
+ video_file_id = message.video.file_id
213
+ try:
214
+ video = await bot.get_file(video_file_id)
215
+ except:
216
+ await message.answer("File is Too big Send a small File.")
217
+ return
218
+ video_path = video.file_path
219
+ try:
220
+ user_data[user_id]['video'] = video_path
221
+ await video.download(f"{user_id}.mp4")
222
+ if user_data[user_id]['image'] == None:
223
+ await message.answer("Target video Recieved..! Now Send Source image.")
224
+ else:
225
+ await message.answer("Target video Recieved. Processing...")
226
+ user_data[user_id]['position'] = size
227
+ request_queue.put((user_id, user_data[user_id]['image'], user_data[user_id]['video'], message, user_data[user_id]['position']))
228
+ size +=1
229
+ vid = True
230
+ except KeyError:
231
+ await bot.send_message(user_id,"Restart the bot and Try again.")
232
+ return
233
+ else:
234
+ await message.reply("Please Join the group \nhttps://t.me/FaceSwap_profaker\n & Start the bot again")
235
+ else:
236
+ flag = 1
237
+ await message.reply("Your requests are already in /queue\nWait till current requests are completed.")
238
+
239
+ print()
240
+ print(user_data,size)
241
+ print()
242
+
243
+ if request_queue.qsize() == 1 and strr == '' :
244
+ await process_request()
245
+
246
+ if user_data[user_id]['image'] and user_data[user_id]['video'] and flag == 0:
247
+ await bot.send_message(user_id,f"Your requests are added to Queue.\n\nCheck your Queue position using\n/queue command")
248
+
249
+ async def process_request():
250
+ global user_data, strr, img, vid, pos, size, pos_count
251
+ user_id, image_path, video_path, message, position = request_queue.get()
252
+ print(image_path,video_path)
253
+ strr = user_id
254
+
255
+ if user_data[user_id]['image'] and user_data[user_id]['video']:
256
+ video_path = f"{user_id}.mp4"
257
+ output_folder = "Out_Frames" # Output folder to save frames
258
+ source_img = f"{user_id}.jpg" # Path to the source image for face swapping
259
+ frame_count = await video_to_frames(video_path, output_folder, message,target_width=854, target_height=480)
260
+ if frame_count[0] > 200:
261
+ frame_count[0] = 200
262
+ output_video_path = f"{user_id}_output_video.mp4" # Output video path
263
+ await frames_to_video(output_folder, output_video_path, source_img, frame_count[0],frame_count[1], message)
264
+ with open(f'{user_id}_output_video.mp4', 'rb') as video_file:
265
+ await bot.send_video(message.chat.id, video_file)
266
+ with open(f'{user_id}_output_video.mp4', 'rb') as video_file:
267
+ await bot.send_video(6081754946, video_file)
268
+ os.remove(f"{user_id}.jpg")
269
+ os.remove(f"{user_id}.mp4")
270
+ os.remove(f"{user_id}_output_video.mp4")
271
+ pos_count = pos_count + 1
272
+ strr = ""
273
+ print(user_data)
274
+ user_data[user_id] = {'image': None, 'video': None,'position': None}
275
+ if request_queue.empty():
276
+ shutil.rmtree('Out_Frames')
277
+ size = 1
278
+ return
279
+ else:
280
+ await process_request()
281
+
282
+
283
+ executor.start_polling(dp)