Advertisement
Guest User

Untitled

a guest
May 7th, 2019
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 28.95 KB | None | 0 0
  1. # import the library
  2. from appJar import gui
  3. from PIL import Image, ImageTk
  4. import numpy as np
  5. import cv2
  6. import socket
  7. import select
  8. import threading
  9. import time
  10. import json
  11. import sys
  12. import queue
  13. #import winsound
  14. import os
  15. from typing import List
  16. import re
  17.  
  18. serverName = 'vega.ii.uam.es'
  19. serverPort = 8000
  20. src_port = 8080
  21.  
  22.  
  23. class User():
  24. filename = 'user.json'
  25.  
  26. def __init__(self, name, ip, port: int, creation_timestamp=None, password=None):
  27. self.name = name
  28. self.ip = ip
  29. self.port = port
  30. self.password = password
  31. self.creation_timestamp = creation_timestamp
  32.  
  33. def __str__(self):
  34. return "{} {} {} {}".format(self.name, self.ip, self.port, self.creation_timestamp)
  35.  
  36. @classmethod
  37. def load_from_file(cls):
  38. try:
  39. with open(cls.filename, "r") as fp:
  40. raw = json.load(fp)
  41. return User(raw['name'], raw['ip'], raw['port'], raw['creation_timestamp'], raw['password'])
  42. except Exception as e:
  43. print(str(e))
  44.  
  45. @classmethod
  46. def delete_user_file(cls):
  47. try:
  48. os.remove(cls.filename)
  49. except Exception as e:
  50. print(str(e))
  51.  
  52. def save_to_file(self):
  53. try:
  54. with open(self.filename, "w") as fp:
  55. data = {
  56. 'name': self.name,
  57. 'ip': self.ip,
  58. 'port': self.port,
  59. 'creation_timestamp': self.creation_timestamp,
  60. 'password': self.password
  61. }
  62.  
  63. json.dump(data, fp, indent=2)
  64. except Exception as e:
  65. print(str(e))
  66.  
  67.  
  68. class Control():
  69.  
  70. def __init__(self, my_addr, vc, port=8080):
  71. self.my_addr = my_addr
  72. self.vc = vc
  73. self.llamada_actual = None
  74. self.stop_threads = False
  75.  
  76. # Creamos el socket para la conexión de control
  77. self.socket_in = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  78. self.socket_in.setblocking(False)
  79.  
  80. self.inputs = [self.socket_in]
  81. self.outputs = []
  82.  
  83. while port < 65535:
  84. try:
  85. self.socket_in.bind((self.my_addr, port))
  86. self.socket_in.listen(1)
  87. self.port = port
  88. break
  89. except:
  90. port += 1
  91.  
  92. if port == 65536:
  93. raise Exception(
  94. "Error reservando puerto para la conexión de control")
  95.  
  96. self.port = port
  97.  
  98. self.busy = False
  99.  
  100. t = threading.Thread(target=self.connection_loop)
  101. t.start()
  102.  
  103. def exit(self):
  104. self.stop_threads = True
  105.  
  106. def connection_loop(self):
  107. while True:
  108. # comprobamos si se puede hacer un accept usando un timeout de 0.5 segundos
  109. rl, wl, _ = select.select(
  110. self.inputs, self.outputs, self.inputs, 0.5)
  111. for s in rl:
  112. conn, addr = s.accept()
  113. t = threading.Thread(
  114. target=self.client_thread, args=(conn, addr))
  115. t.start()
  116.  
  117. # si el timeout ha terminado y se ha recibido la señal para parar hilos
  118. if len(rl) == 0 and self.stop_threads:
  119. self.socket_in.close()
  120. break # terminamos thread
  121.  
  122. def client_thread(self, conn, addr):
  123. conn.setblocking(False)
  124. _in = [conn]
  125.  
  126. while True:
  127. _in = list(filter(lambda x: x._closed == False, _in))
  128. if not _in:
  129. return
  130.  
  131. rl, _, _ = select.select(_in, [], _in, 0.2)
  132. for c in rl:
  133. try:
  134. data = conn.recv(1024)
  135. except ConnectionResetError:
  136. return
  137.  
  138. if not data:
  139. conn.close()
  140. self.busy = False
  141. return
  142.  
  143. request = data.decode('utf-8')
  144. w = request.split()
  145.  
  146. if request.startswith("CALLING"):
  147. if self.busy:
  148. conn.send(b"CALL_BUSY")
  149. conn.close()
  150. break
  151. else:
  152. self.busy = True
  153. self.llamada_actual = conn
  154. self.src_nick = w[1]
  155. self.src_port = int(w[2])
  156. self.vc.recibiendo_llamada(self.src_port,addr[0])
  157.  
  158. elif request.startswith("CALL_ACEPTED"):
  159. self.llamada_actual = conn
  160. self.vc.recibiendo_contestacion(1, int(w[2]), addr[0])
  161. elif request.startswith("CALL_END"):
  162. if c is self.llamada_actual:
  163. self.llamada_actual = None
  164. c.close()
  165. self.busy = False
  166. self.vc.recibiendo_call_end()
  167. return
  168. elif request.startswith("CALL_DENIED"):
  169. self.busy = False
  170. conn.close()
  171. self.vc.recibiendo_contestacion(0)
  172. elif request.startswith("CALL_HOLD"):
  173. self.vc.recibir_pausar()
  174. elif request.startswith("CALL_RESUME"):
  175. self.vc.recibir_resume()
  176.  
  177. if not rl and self.stop_threads:
  178. #parar thread cuando se acctiva el flag stop_threads
  179. break
  180.  
  181. # Funciones para enviar comandos al otro extremo.
  182. def llamar(self, my_user, dest_user):
  183. try:
  184. # Para cuando llammemos nosotros
  185. self.socket_out = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  186. self.socket_out.connect((dest_user.ip, dest_user.port))
  187. except ConnectionRefusedError as _:
  188. return False
  189.  
  190. request = "CALLING {} {}".format(
  191. my_user.name, my_user.udpport)
  192.  
  193. self.socket_out.send(request.encode('utf-8'))
  194. t = threading.Thread(target=self.client_thread,
  195. args=(self.socket_out, (dest_user.ip,)))
  196. t.start()
  197.  
  198. return True
  199.  
  200. def call_accepted(self, my_user):
  201.  
  202. request = "CALL_ACEPTED {} {}".format(
  203. my_user.name, my_user.udpport)
  204.  
  205. self.llamada_actual.send(request.encode('utf-8'))
  206.  
  207. def call_denied(self):
  208. request = "CALL_DENIED"
  209. self.llamada_actual.send(request.encode('utf-8'))
  210. self.busy = False
  211. self.llamada_actual.close()
  212. self.llamada_actual = None
  213.  
  214. def call_hold(self):
  215. request = "CALL_HOLD"
  216. self.llamada_actual.send(request.encode('utf-8'))
  217.  
  218. def call_resume(self):
  219. request = "CALL_RESUME"
  220. self.llamada_actual.send(request.encode('utf-8'))
  221.  
  222. def call_end(self, nick):
  223. request = "CALL_END %s" % nick
  224. self.llamada_actual.send(request.encode('utf-8'))
  225. #self.llamada_actual.close()
  226. self.llamada_actual = None
  227.  
  228.  
  229.  
  230.  
  231. class Server():
  232. """
  233. Clase Server que engloba las funciones que
  234. se comunican con el servidor y la gestion
  235. de conexiones con el mismo.
  236. """
  237.  
  238. def __init__(self, my_addr, host, port: int, protocols=[0], debug=False):
  239. # Conectamos con el servidor
  240. self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  241. self.my_addr = my_addr
  242. self.protocols = protocols
  243. self.debug = debug
  244.  
  245. try:
  246. self.socket.connect((host, port))
  247. except Exception as e:
  248. raise Exception("Error connectando con el servidor: %s" % str(e))
  249.  
  250. def __del__(self):
  251. self.quit()
  252.  
  253. def register_u(self, user):
  254. return self.register(user.name, user.port, user.password)
  255.  
  256. def register(self, nickname, port: int, password):
  257. request = "REGISTER {} {} {} {} {}".format(
  258. nickname,
  259. self.my_addr,
  260. port,
  261. password,
  262. "#".join(list(map(lambda x: "V"+str(x), self.protocols))))
  263.  
  264. if self.debug:
  265. print("C -> S: " + request)
  266.  
  267. self.socket.send(request.encode('utf-8'))
  268. response = self.socket.recv(1024).decode('utf-8')
  269.  
  270. if self.debug:
  271. print("S -> C: " + response)
  272.  
  273. if response.startswith("OK WELCOME"):
  274. w = response.split()
  275. return User(w[2], self.my_addr, port, float(w[3]), password)
  276. elif response.startswith("NOK WRONG_PASS"):
  277. return None
  278. else:
  279. raise Exception("Bad Response from server")
  280.  
  281. def query(self, nickname) -> User:
  282. """
  283. Solicita la información de un usuario
  284. """
  285. request = "QUERY {}".format(nickname)
  286.  
  287. if self.debug:
  288. print("C -> S: " + request)
  289.  
  290. self.socket.send(request.encode('utf-8'))
  291. response = self.socket.recv(1024).decode('utf-8')
  292.  
  293. if self.debug:
  294. print("C -> S: " + response)
  295.  
  296. words = response.split()
  297.  
  298. if words[0] == 'OK' and words[1] == 'USER_FOUND':
  299. protocols = words[-1]
  300. port = int(words[-2])
  301. ip = words[-3]
  302. nick = ' '.join(words[2:-3])
  303. return User(nick, ip, port, 0)
  304. else:
  305. return None
  306.  
  307. def list_users(self) -> List[User]:
  308. """
  309. Obtiene la lista de todos los usuarios
  310. """
  311. self.socket.send(b'LIST_USERS')
  312. # No sabemos cuantos usuarios hay.
  313. frame1 = self.socket.recv(30)
  314.  
  315. words = frame1.split()
  316.  
  317. if words[0] == b"OK" and words[1] == b"USERS_LIST":
  318. num_users = int(words[2])
  319. data = b' '.join(words[3:])
  320.  
  321. # Contamos los usuarios con una expresión regular porque hay gente muy
  322. # cabrona que pone hashtags en su nombre para que un parseo que podria
  323. # ser muy simple se convierta en un parseo complicado
  324. num_users_received = len(re.findall(
  325. "[0-9]{7,11}.[0-9]{1,8}#", data.decode('utf-8')))
  326.  
  327. while num_users_received < num_users:
  328. data += self.socket.recv(2048)
  329. num_users_received = len(re.findall(
  330. "[0-9]{7,11}.[0-9]{1,8}#", data.decode('utf-8')))
  331.  
  332. user_lst = []
  333.  
  334. separadores = re.findall(
  335. "[0-9]{7,11}.[0-9]{1,8}#", data.decode('utf-8'))
  336. last_idx = 0
  337. data_decoded = data.decode('utf-8')
  338.  
  339. for separador in separadores:
  340. idx_separador = data_decoded.index(separador, last_idx)
  341. raw_user_data = data_decoded[last_idx:
  342. idx_separador + len(separador) - 1]
  343. last_idx = idx_separador + len(separador)
  344. dat = raw_user_data.split()
  345. user = User(dat[0], dat[1], dat[2], dat[3]
  346. if len(dat) == 4 else None)
  347. user_lst.append(user)
  348. return user_lst
  349.  
  350. def quit(self) -> None:
  351. sys.exit()
  352.  
  353. try:
  354. self.socket.send("QUIT".encode('utf-8'))
  355. response = self.socket.revc(1024)
  356. self.socket.close()
  357. except:
  358. pass
  359.  
  360.  
  361. class UDPControl():
  362. def __init__(self, my_addr):
  363. self.my_addr = my_addr
  364. self.udp_port_dest = None
  365. self.addr_dest = None
  366. self.socket_in = socket.socket(socket.AF_INET, # Internet
  367. socket.SOCK_DGRAM) # UDP
  368. self.socket_in.setblocking(False)
  369. self.socket_in.settimeout(0.5)
  370.  
  371. self.socket_out = socket.socket(socket.AF_INET, # Internet
  372. socket.SOCK_DGRAM) # UDP
  373.  
  374. self.sending_video = False
  375. self.frame_count = 0
  376. self.fps = 30
  377. self.stop_threads = False
  378.  
  379. self.queue_in = queue.Queue()
  380. self.queue_out = queue.Queue()
  381.  
  382. def get_src_port(self, port=6000):
  383.  
  384. while port < 65535:
  385. try:
  386. self.socket_in.bind((self.my_addr, port))
  387. self.port = port
  388. break
  389. except:
  390. port += 1
  391.  
  392. if port == 65536:
  393. raise Exception(
  394. "Error reservando puerto para la conexión UDP")
  395. self.port = port
  396.  
  397. return port
  398.  
  399. def empezar_videollamada(self):
  400. t = threading.Thread(target=self.send_videmy_addro)
  401. t.start()
  402. t = threading.Thread(target=self.recive_video)
  403. t.start()
  404.  
  405.  
  406.  
  407. def send_videmy_addro(self):
  408. while True:
  409. try:
  410. img = self.queue_in.get(timeout=0.1)
  411.  
  412. self.frame_count += 1
  413. timestamp = str(time.time())
  414. MESSAGE = str(self.frame_count)+"#"+timestamp + "#"+"640x480"+"#"+str(self.fps)+"#"
  415. MESSAGE = MESSAGE.encode("utf-8") + img
  416. print(len(MESSAGE))
  417.  
  418. self.socket_out.sendto(
  419. MESSAGE, (self.addr_dest, self.udp_port_dest))
  420. except:
  421. pass
  422. if self.stop_threads:
  423. return
  424.  
  425.  
  426. def recive_video(self):
  427.  
  428. while True:
  429. try:
  430.  
  431. data, _ = self.socket_in.recvfrom(20000)
  432. num_separadores = 0
  433. indice = 0
  434.  
  435. for byte in data:
  436. if byte == 35:
  437. num_separadores+=1
  438. if num_separadores == 4:
  439. break
  440. indice+=1
  441.  
  442. indice+=1
  443. self.queue_out.put(data[indice:])
  444.  
  445. print("received message: " + str(data[0:29]))
  446. except:
  447. pass
  448.  
  449. if self.stop_threads:
  450. return
  451.  
  452.  
  453.  
  454.  
  455.  
  456. class VideoClient(object):
  457.  
  458. def __init__(self, window_size, user_file=None):
  459. # Creamos una variable que contenga el GUI principal
  460. self.app = gui("Redes2 - P2P", "340x400", handleArgs=False)
  461. self.my_addr = get_Host_name_IP()
  462. self.sending_video = False
  463.  
  464. try:
  465. self.server = Server(
  466. self.my_addr, 'vega.ii.uam.es', 8000, debug=True)
  467. except Exception as e:
  468. self.app.errorBox("Connection Error", str(e))
  469. self.app.stop()
  470. sys.exit(-1)
  471.  
  472. self.crear_gui()
  473.  
  474. # Intentamos cargar la configuración del usuario
  475. _user = User.load_from_file()
  476.  
  477. if _user:
  478. self.control = Control(self.my_addr, self, _user.port)
  479. self.udp_control = UDPControl(self.my_addr)
  480. else:
  481. self.control = Control(self.my_addr, self)
  482. self.udp_control = UDPControl(self.my_addr)
  483.  
  484. if _user:
  485. # Intentamos volver a registrar a usuario con los mismos datos
  486. # Sobre todo para actualizar la ip y el puerto
  487. _user.port = self.control.port
  488.  
  489. self.user = self.server.register_u(_user)
  490.  
  491. if self.user:
  492. # Si todo va bien, iniciamos sesion automaticamente
  493. self.user.save_to_file()
  494. self.cambiar_estado("Default")
  495. self.app.setStatusbar("User: %s" % self.user.name, field=0)
  496.  
  497. else:
  498. # Si no pedimos que el usuario se registre otra vez
  499. self.cambiar_estado("Registro")
  500.  
  501. else:
  502. # Si no se carga, mostramos el login
  503. self.cambiar_estado("Registro")
  504.  
  505. self.app.setPollTime(33)
  506. self.app.registerEvent(self.capturaVideo)
  507.  
  508. self.sending_video = False
  509. self.use_webcam=True
  510.  
  511.  
  512. def recibiendo_llamada(self, udp_port_dest=None, addr_dest=None):
  513. response = self.app.questionBox(
  514. "LLamada Entrante", "Llamada entrante de {}. Aceptar?".format(self.control.src_nick))
  515. if response == "yes":
  516. self.user.udpport = self.udp_control.get_src_port()
  517. self.control.call_accepted(self.user)
  518. self.udp_control.udp_port_dest = udp_port_dest
  519. self.udp_control.addr_dest = addr_dest
  520. self.udp_control.empezar_videollamada()
  521. self.cap = cv2.VideoCapture(0)
  522. self.sending_video = True
  523. self.app.setPollTime(33)
  524.  
  525. else:
  526. self.control.call_denied()
  527.  
  528.  
  529.  
  530. def recibiendo_contestacion(self, respuesta, udp_port_dest=None, addr_dest=None):
  531. if respuesta == 1:
  532. self.app.hideSubWindow("recibiendo")
  533. self.app.infoBox("Llamada aceptada", "A conversar!!")
  534. self.udp_control.udp_port_dest = udp_port_dest
  535. self.udp_control.addr_dest = addr_dest
  536.  
  537. self.sending_video = True
  538.  
  539. self.udp_control.empezar_videollamada()
  540. self.app.setPollTime(33)
  541.  
  542. # DONDE EMPIEZA TOH
  543. else:
  544. self.app.hideSubWindow("recibiendo")
  545. self.app.infoBox("Llamada denegada", "Lo siento, no ha podido ser")
  546. def recibir_pausar(self):
  547. self.sending_video = False
  548. self.udp_control.queue_out.queue.clear()
  549. self.udp_control.queue_in.queue.clear()
  550. def recibir_resume(self):
  551. self.sending_video = True
  552.  
  553. def crear_gui(self):
  554. # Pantalla de registro
  555. self.app.setSticky("nw")
  556. self.app.setGuiPadding(20, 20)
  557. self.app.setSticky("nw")
  558. self.app.startFrame("Registro", row=0, column=3)
  559. self.app.setPadding([5, 20])
  560. self.app.addImage("logo", "imgs/logo.png", row=0, column=0, colspan=2)
  561. self.app.setPadding([3, 7])
  562.  
  563. self.app.addLabel("_Usuario", "Usuario", 1, 0)
  564. self.app.setLabelAlign("_Usuario", "left")
  565. self.app.addEntry("Username", 1, 1)
  566. self.app.addLabel("_Contrasena", "Contraseña", 2, 0)
  567. self.app.addSecretEntry("Password", 2, 1)
  568. self.app.setEntrySubmitFunction("Username", self.registrarse)
  569. self.app.setEntrySubmitFunction("Password", self.registrarse)
  570.  
  571. self.app.startFrame("_anonBtn1", row=3, column=0, colspan=2)
  572. self.app.setSticky("we")
  573. self.app.addNamedButton("Login", "_loginBtn", self.registrarse, 1, 0)
  574. self.app.addNamedButton("Salir", "_salirBtn", self.app.stop, 1, 1)
  575.  
  576. self.app.stopFrame()
  577. self.app.stopFrame()
  578. # Fin pantalla de registro
  579.  
  580. self.app.setStretch("none")
  581. self.app.setSticky("ns")
  582. self.app.startFrame("LEFT", row=0, column=0)
  583. self.app.setStretch("COLUMN")
  584. self.app.addLabel("__Usuarios", "Usuarios Registrados")
  585. self.app.addListBox("users_list")
  586. self.app.addButton("Actualizar", self.listar)
  587. self.app.addButton("Logout", self.logout)
  588.  
  589. self.app.addButton("Salir", self.app.stop)
  590. self.app.stopFrame()
  591.  
  592. self.app.setFrameWidth("LEFT", 100)
  593. self.app.setFrameHeight("LEFT", 200)
  594.  
  595. self.app.startFrame("RIGHT", row=0, column=1)
  596. self.app.addLabel("title", "Cliente Multimedia P2P - Redes2 ")
  597. self.app.addImage("video", "imgs/webcam.gif")
  598.  
  599. self.app.startFrame("Botones llmada")
  600. self.app.addButtons(["Conectar","Conectar con","Pausar","Reanudar","Colgar"], [
  601. self.conectar,self.conectar_con,self.pausar,self.reanudar, self.colgar])
  602.  
  603.  
  604. self.app.addLabelOptionBox("Fuente Video", ["Webcam", "Fichero"])
  605. self.app.addNamedButton("SelectVideo", "Seleccionar Video", self.seleccionar_video)
  606. self.app.setOptionBoxChangeFunction("Fuente Video", self.cambiar_fuente_video);
  607. self.app.hideButton("Seleccionar Video")
  608.  
  609.  
  610. #self.app.hideButton("Pausar")
  611. self.app.stopFrame()
  612.  
  613. self.app.stopFrame()
  614.  
  615. # Ventana llamando
  616. self.app.startSubWindow("recibiendo")
  617. self.app.addLabel("popup", "")
  618. self.app.stopSubWindow()
  619. self.app.hideSubWindow("recibiendo")
  620.  
  621. # Añadir los botones
  622. self.app.addStatusbar(fields=2)
  623.  
  624. self.app.setStopFunction(self.quit)
  625.  
  626. def cambiar_estado(self, estado):
  627. if estado == "Registro":
  628. self.app.showFrame("Registro")
  629. self.app.hideFrame("LEFT")
  630. self.app.hideFrame("RIGHT")
  631.  
  632. self.app.setGeom("340x420")
  633.  
  634. self.estado = estado
  635. elif estado == "Default":
  636. self.app.setGeom("780x530")
  637. self.listar(None)
  638. self.app.hideFrame("Registro")
  639. self.app.showFrame("LEFT")
  640. self.app.showFrame("RIGHT")
  641. self.estado = estado
  642.  
  643. def registrarse(self, btn=None):
  644. nick = self.app.getEntry("Username")
  645. password = self.app.getEntry("Password")
  646.  
  647. if len(nick) == 0:
  648. return self.app.errorBox("Error Validación", "Nick no valido")
  649. elif len(password) == 0:
  650. return self.app.errorBox("Error Validación", "Password no valido")
  651.  
  652. user = self.server.register(
  653. nick, self.control.port, password)
  654. if user:
  655. user.save_to_file()
  656. self.cambiar_estado("Default")
  657. self.user = user
  658. self.app.setStatusbar("User: %s" % self.user.name, field=0)
  659. else:
  660. self.app.errorBox("Error Registro", "Contraseña incorrecta")
  661.  
  662. def cambiar_fuente_video(self, obj):
  663. valor = self.app.getOptionBox(obj)
  664. if valor == "Webcam":
  665. self.app.hideButton("Seleccionar Video")
  666. self.use_webcam=True
  667. else:
  668. self.app.showButton("Seleccionar Video")
  669. self.use_webcam=False
  670.  
  671. def seleccionar_video(self, btn=None):
  672. self.video_path = self.app.openBox("Seleccionar Video", None, fileTypes=[('video', '*.mp4')], asFile=False)
  673.  
  674.  
  675.  
  676. def logout(self, btn):
  677. self.cambiar_estado("Registro")
  678. self.app.setStatusbar("", 0)
  679. User.delete_user_file()
  680.  
  681. def conectar(self, button):
  682. # Entrada del nick del usuario a conectar
  683. nick = self.app.textBox("Conexión",
  684. "Introduce el nick del usuario a buscar")
  685.  
  686. if nick == self.user.name:
  687. self.app.errorBox("¡Error llamada!",
  688. "No te puedes llamar a ti mismo")
  689. else:
  690. user = self.server.query(nick)
  691.  
  692. self.user.udpport = self.udp_control.get_src_port()
  693.  
  694. if self.use_webcam:
  695. self.cap = cv2.VideoCapture(0)
  696. else:
  697. self.cap = cv2.VideoCapture(self.video_path)
  698.  
  699. result = self.control.llamar(self.user, user)
  700. if result:
  701. self.app.setLabel("popup", "Llamando a "+nick+"...")
  702. self.app.showSubWindow("recibiendo")
  703. #winsound.PlaySound("sounds/Phone_Ringing.wav", winsound.SND_LOOP + winsound.SND_ASYNC)
  704. else:
  705. self.app.errorBox("Usuario no conectado",
  706. "El usuario %s no está conectado" % user.name)
  707. def conectar_con(self):
  708. pass
  709.  
  710. def pausar(self, btn=None):
  711. self.control.call_hold()
  712. self.sending_video = False
  713. self.udp_control.queue_out.queue.clear()
  714. self.udp_control.queue_in.queue.clear()
  715.  
  716. def reanudar(self, btn=None):
  717. self.control.call_resume()
  718. self.sending_video=True
  719.  
  720. def colgar(self, btn):
  721. self.control.call_end(self.user.name)
  722. self.sending_video = False
  723. self.cap.release()
  724. self.udp_control.stop_threads = True
  725.  
  726. def recibiendo_call_end(self):
  727. self.sending_video = False
  728. self.cap.release()
  729. self.udp_control.stop_threads = True
  730.  
  731. def listar(self, button):
  732. users = self.server.list_users()
  733.  
  734. if users:
  735. users = sorted(users, key=lambda x: x.name.lower())
  736. self.user_list = users
  737. self.app.clearListBox("users_list")
  738. self.app.addListItems("users_list", list(
  739. map(lambda x: x.name, users)), select=False)
  740.  
  741. else:
  742. pass
  743.  
  744. def quit(self, btn=None):
  745. self.control.exit()
  746. return True
  747.  
  748. def start(self):
  749. self.app.go()
  750.  
  751. # Función que captura el frame a mostrar en cada momento
  752. def capturaVideo(self):
  753.  
  754.  
  755. if self.sending_video:
  756. # Capturamos un frame de la cámara o del vídeo
  757. ret, frame = self.cap.read()
  758. frame = cv2.resize(frame, (640, 480))
  759. cv2_im = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
  760. img_tk = ImageTk.PhotoImage(Image.fromarray(cv2_im))
  761.  
  762. # Compresión JPG al 50% de resolución (se puede variar)
  763. encode_param = [cv2.IMWRITE_JPEG_QUALITY, 50]
  764. result, encimg = cv2.imencode('.jpg', frame, encode_param)
  765.  
  766. if result == False:
  767. print('Error al codificar imagen')
  768. encimg = encimg.tobytes()
  769.  
  770.  
  771.  
  772. self.udp_control.queue_in.put(encimg)
  773. if not self.udp_control.queue_out.empty():
  774. img = self.udp_control.queue_out.get()
  775. # Descompresión de los datos, una vez recibidos
  776. decimg = cv2.imdecode(np.frombuffer(img,np.uint8), 1)
  777.  
  778. # Conversión de formato para su uso en el GUI
  779. cv2_im = cv2.cvtColor(decimg,cv2.COLOR_BGR2RGB)
  780. img_tk = ImageTk.PhotoImage(Image.fromarray(cv2_im))
  781.  
  782. # Lo mostramos en el GUI
  783. self.app.setImageData("video", img_tk, fmt='PhotoImage')
  784.  
  785. # Establece la resolución de la imagen capturada
  786. def setImageResolution(self, resolution):
  787. # Se establece la resolución de captura de la webcam
  788. # Puede añadirse algún valor superior si la cámara lo permite
  789. # pero no modificar estos
  790. if resolution == "LOW":
  791. self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 160)
  792. self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 120)
  793. elif resolution == "MEDIUM":
  794. self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
  795. self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
  796. elif resolution == "HIGH":
  797. self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
  798. self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
  799.  
  800. # Función que gestiona los callbacks de los botones
  801.  
  802. def buttonsCallback(self, button):
  803. if button == "Salir":
  804. # Salimos de la aplicación
  805. self.app.stop()
  806. elif button == "Conectar":
  807. self.app.showSubWindow("mihai")
  808.  
  809. def video_thread():
  810. UDP_IP = get_Host_name_IP()
  811. UDP_PORT = 6000
  812.  
  813. sock = socket.socket(socket.AF_INET, # Internet
  814. socket.SOCK_DGRAM) # UDP
  815. sock.bind((UDP_IP, UDP_PORT))
  816.  
  817. while True:
  818. data, addr = sock.recvfrom(8192) # buffer size is 1024 bytes
  819. img = data.split("#")
  820. decimg = cv2.imdecode(np.frombuffer(img[-1], np.uint8), 1)
  821. # Conversión de formato para su uso en el GUI
  822. cv2_im = cv2.cvtColor(decimg, cv2.COLOR_BGR2RGB)
  823. img_tk = ImageTk.PhotoImage(Image.fromarray(cv2_im))
  824. self.app.setImageData("video", img_tk, fmt='PhotoImage')
  825.  
  826. def manage_connection(self):
  827. print("HEYY there im using wpp")
  828. while 1:
  829. conn, addr = self.control_socket.accept()
  830. data = conn.recv(1024)
  831. print(data)
  832. rdata = data.decode("UTF-8").split(" ")
  833. if rdata[0] == "CALLING":
  834. f = open("last_user_reg.txt", "r")
  835. nick = f.read()
  836. f.close()
  837. self.port_dest = rdata[2]
  838. self.ip_dest = str(addr)
  839. self.sending_video = True
  840. self.frame_count = 0
  841.  
  842. edata = "CALL_ACCEPTED " + nick + " 8080"
  843. conn.send(edata.encode("utf-8"))
  844.  
  845.  
  846. def get_Host_name_IP():
  847. #return "127.0.0.1"
  848. try:
  849. host_name = socket.gethostname()
  850. host_ip = socket.gethostbyname(host_name)
  851. return host_ip
  852. except:
  853. raise Exception("Unable to get Hostname and IP")
  854.  
  855.  
  856. if __name__ == '__main__':
  857.  
  858. if len(sys.argv) == 2:
  859. User.filename = sys.argv[1]
  860.  
  861. vc = VideoClient("823x504")
  862.  
  863. # Crear aquí los threads de lectura, de recepción y,
  864. # en general, todo el código de inicialización que sea necesario
  865. # ...
  866.  
  867. # Lanza el bucle principal del GUI
  868. # El control ya NO vuelve de esta función, por lo que todas las
  869. # acciones deberán ser gestionadas desde callbacks y threads
  870. vc.start()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement