class Client: def __init__(self): self.socket = socket.socket() self.socket.settimeout(5) self.buffer_size = 2048 self.vsock = videosocket.VideoSocket(self.socket) self.is_video_call = False self.videofeed = None self.connected = True def receive(self): while self.connected: if self.is_video_call: if not self.videofeed: self.videofeed = VideoFeed("client_cam", 1) frame = self.videofeed.get_frame() self.vsock.vsend(frame) rcvd_frame = self.vsock.vreceive() try: if rcvd_frame == 2: self.is_video_call = False self.vsock.vsend(bytes("-2", ENCODING)) self.videofeed.destroy() continue except: pass quit = self.videofeed.set_frame(rcvd_frame) if quit: # inform other party that user wants to quit self.vsock.vsend(bytes("-1", ENCODING)) self.is_video_call = False else: # free up webcam in case not in use if self.videofeed: self.videofeed = None msg = self.socket.recv(self.buffer_size) try: decoded_msg = msg.decode(ENCODING) except: continue if decoded_msg == "VIDEO_CALL_START": self.send(bytes("READY_FOR_VIDEO_CALL", ENCODING)) self.is_video_call = True elif decoded_msg == "READY_FOR_VIDEO_CALL": self.is_video_call = True elif decoded_msg == "VIDEO_CALL_INITIATE": self.initiate_video_call() elif decoded_msg == "VIDEO_CALL_ACCEPT" or decoded_msg == "VIDEO_CALL_REJECTED": self.send(msg) elif "VIDEO_CALL_REQUEST" in decoded_msg: # someone wants to videochat with you from_uname = decoded_msg.split('$')[-1] self.receive_vcall(from_uname) else: self.update_gui(msg, False) def send(self, msg=None): if msg is None: msg = msg_box.get() msg_box.delete(0, tk.END) self.socket.send(bytes(msg, ENCODING)) else: self.socket.send(msg) def initiate_video_call(self): self.send(bytes("VIDEO_CALL_START", ENCODING)) usernames = self.socket.recv(self.buffer_size).decode(ENCODING) names = usernames.split("$")[:-1] num_online = len(names) root = tk.Tk() root.geometry("300x%s" % (str((2 + num_online) * 100))) if num_online == 0: l = tk.Label(root, text="No users online, try again later!!", padx=20, pady=10) l.pack() else: l = tk.Label(root, text="Select the person whose face you want to see!!", padx=20, pady=20) l.pack() for i in range(len(names)): b = tk.Button( root, text=names[i], command=lambda name=names[i]: self.decide_target(root, name)) b.pack() qb = tk.Button(root, text="Quit", command=lambda: self.decide_target(root, None)) qb.pack() root.mainloop() def decide_target(self, root, target): if target: self.send(bytes(target, ENCODING)) else: self.send(bytes("VIDEO_CALL_ABORT", ENCODING)) root.destroy() def update_gui(self, msg, is_sent=False): display_listbox.insert("end", msg.decode(ENCODING)) def receive_vcall(self, from_uname): # get username of who wants to talk with you root = tk.Tk() root.geometry("300x300") l = tk.Label(root, text="Your beloved %s wants to see your face !!" % (from_uname), padx=20, pady=20) l.pack() b1 = tk.Button( root, text="Accept", command=lambda: self.send_confirmation(root, from_uname, True)) b1.pack() b2 = tk.Button( root, text="Reject", command=lambda: self.send_confirmation(root, from_uname, False)) b2.pack() root.mainloop() def send_confirmation(self, root, accept_from, decision): if decision: msg = bytes("VIDEO_CALL_ACCEPT", ENCODING) else: msg = bytes("VIDEO_CALL_REJECTED", ENCODING) self.send(msg) time.sleep(1) self.send(bytes(accept_from, ENCODING)) root.destroy()