Advertisement
Guest User

Untitled

a guest
May 7th, 2019
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 28.87 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.  
  369. self.socket_out = socket.socket(socket.AF_INET, # Internet
  370. socket.SOCK_DGRAM) # UDP
  371.  
  372. self.sending_video = False
  373. self.frame_count = 0
  374. self.fps = 30
  375. self.stop_threads = False
  376.  
  377. self.queue_in = queue.Queue()
  378. self.queue_out = queue.Queue()
  379.  
  380. def get_src_port(self, port=6000):
  381.  
  382. while port < 65535:
  383. try:
  384. self.socket_in.bind((self.my_addr, port))
  385. self.port = port
  386. break
  387. except:
  388. port += 1
  389.  
  390. if port == 65536:
  391. raise Exception(
  392. "Error reservando puerto para la conexión UDP")
  393. self.port = port
  394.  
  395. return port
  396.  
  397. def empezar_videollamada(self):
  398. t = threading.Thread(target=self.send_videmy_addro)
  399. t.start()
  400. t = threading.Thread(target=self.recive_video)
  401. t.start()
  402.  
  403.  
  404.  
  405. def send_videmy_addro(self):
  406. while True:
  407. try:
  408. img = self.queue_in.get(timeout=0.1)
  409.  
  410. self.frame_count += 1
  411. timestamp = str(time.time())
  412. MESSAGE = str(self.frame_count)+"#"+timestamp + "#"+"640x480"+"#"+str(self.fps)+"#"
  413. MESSAGE = MESSAGE.encode("utf-8") + img
  414. print(len(MESSAGE))
  415.  
  416. self.socket_out.sendto(
  417. MESSAGE, (self.addr_dest, self.udp_port_dest))
  418. except:
  419. pass
  420. if self.stop_threads:
  421. return
  422.  
  423.  
  424. def recive_video(self):
  425.  
  426. while True:
  427. try:
  428.  
  429. data, _ = self.socket_in.recvfrom(20000)
  430. num_separadores = 0
  431. indice = 0
  432.  
  433. for byte in data:
  434. if byte == 35:
  435. num_separadores+=1
  436. if num_separadores == 4:
  437. break
  438. indice+=1
  439.  
  440. indice+=1
  441. self.queue_out.put(data[indice:])
  442.  
  443. print("received message: " + str(data[0:29])
  444. except:
  445. pass
  446. if self.stop_threads:
  447. return
  448.  
  449. )
  450.  
  451.  
  452.  
  453. class VideoClient(object):
  454.  
  455. def __init__(self, window_size, user_file=None):
  456. # Creamos una variable que contenga el GUI principal
  457. self.app = gui("Redes2 - P2P", "340x400", handleArgs=False)
  458. self.my_addr = get_Host_name_IP()
  459. self.sending_video = False
  460.  
  461. try:
  462. self.server = Server(
  463. self.my_addr, 'vega.ii.uam.es', 8000, debug=True)
  464. except Exception as e:
  465. self.app.errorBox("Connection Error", str(e))
  466. self.app.stop()
  467. sys.exit(-1)
  468.  
  469. self.crear_gui()
  470.  
  471. # Intentamos cargar la configuración del usuario
  472. _user = User.load_from_file()
  473.  
  474. if _user:
  475. self.control = Control(self.my_addr, self, _user.port)
  476. self.udp_control = UDPControl(self.my_addr)
  477. else:
  478. self.control = Control(self.my_addr, self)
  479. self.udp_control = UDPControl(self.my_addr)
  480.  
  481. if _user:
  482. # Intentamos volver a registrar a usuario con los mismos datos
  483. # Sobre todo para actualizar la ip y el puerto
  484. _user.port = self.control.port
  485.  
  486. self.user = self.server.register_u(_user)
  487.  
  488. if self.user:
  489. # Si todo va bien, iniciamos sesion automaticamente
  490. self.user.save_to_file()
  491. self.cambiar_estado("Default")
  492. self.app.setStatusbar("User: %s" % self.user.name, field=0)
  493.  
  494. else:
  495. # Si no pedimos que el usuario se registre otra vez
  496. self.cambiar_estado("Registro")
  497.  
  498. else:
  499. # Si no se carga, mostramos el login
  500. self.cambiar_estado("Registro")
  501.  
  502. self.app.setPollTime(33)
  503. self.app.registerEvent(self.capturaVideo)
  504.  
  505. self.sending_video = False
  506. self.use_webcam=True
  507.  
  508.  
  509. def recibiendo_llamada(self, udp_port_dest=None, addr_dest=None):
  510. response = self.app.questionBox(
  511. "LLamada Entrante", "Llamada entrante de {}. Aceptar?".format(self.control.src_nick))
  512. if response == "yes":
  513. self.user.udpport = self.udp_control.get_src_port()
  514. self.control.call_accepted(self.user)
  515. self.udp_control.udp_port_dest = udp_port_dest
  516. self.udp_control.addr_dest = addr_dest
  517. self.udp_control.empezar_videollamada()
  518. self.cap = cv2.VideoCapture(0)
  519. self.sending_video = True
  520. self.app.setPollTime(33)
  521.  
  522. else:
  523. self.control.call_denied()
  524.  
  525.  
  526.  
  527. def recibiendo_contestacion(self, respuesta, udp_port_dest=None, addr_dest=None):
  528. if respuesta == 1:
  529. self.app.hideSubWindow("recibiendo")
  530. self.app.infoBox("Llamada aceptada", "A conversar!!")
  531. self.udp_control.udp_port_dest = udp_port_dest
  532. self.udp_control.addr_dest = addr_dest
  533.  
  534. self.sending_video = True
  535.  
  536. self.udp_control.empezar_videollamada()
  537. self.app.setPollTime(33)
  538.  
  539. # DONDE EMPIEZA TOH
  540. else:
  541. self.app.hideSubWindow("recibiendo")
  542. self.app.infoBox("Llamada denegada", "Lo siento, no ha podido ser")
  543. def recibir_pausar(self):
  544. self.sending_video = False
  545. self.udp_control.queue_out.queue.clear()
  546. self.udp_control.queue_in.queue.clear()
  547. def recibir_resume(self):
  548. self.sending_video = True
  549.  
  550. def crear_gui(self):
  551. # Pantalla de registro
  552. self.app.setSticky("nw")
  553. self.app.setGuiPadding(20, 20)
  554. self.app.setSticky("nw")
  555. self.app.startFrame("Registro", row=0, column=3)
  556. self.app.setPadding([5, 20])
  557. self.app.addImage("logo", "imgs/logo.png", row=0, column=0, colspan=2)
  558. self.app.setPadding([3, 7])
  559.  
  560. self.app.addLabel("_Usuario", "Usuario", 1, 0)
  561. self.app.setLabelAlign("_Usuario", "left")
  562. self.app.addEntry("Username", 1, 1)
  563. self.app.addLabel("_Contrasena", "Contraseña", 2, 0)
  564. self.app.addSecretEntry("Password", 2, 1)
  565. self.app.setEntrySubmitFunction("Username", self.registrarse)
  566. self.app.setEntrySubmitFunction("Password", self.registrarse)
  567.  
  568. self.app.startFrame("_anonBtn1", row=3, column=0, colspan=2)
  569. self.app.setSticky("we")
  570. self.app.addNamedButton("Login", "_loginBtn", self.registrarse, 1, 0)
  571. self.app.addNamedButton("Salir", "_salirBtn", self.app.stop, 1, 1)
  572.  
  573. self.app.stopFrame()
  574. self.app.stopFrame()
  575. # Fin pantalla de registro
  576.  
  577. self.app.setStretch("none")
  578. self.app.setSticky("ns")
  579. self.app.startFrame("LEFT", row=0, column=0)
  580. self.app.setStretch("COLUMN")
  581. self.app.addLabel("__Usuarios", "Usuarios Registrados")
  582. self.app.addListBox("users_list")
  583. self.app.addButton("Actualizar", self.listar)
  584. self.app.addButton("Logout", self.logout)
  585.  
  586. self.app.addButton("Salir", self.app.stop)
  587. self.app.stopFrame()
  588.  
  589. self.app.setFrameWidth("LEFT", 100)
  590. self.app.setFrameHeight("LEFT", 200)
  591.  
  592. self.app.startFrame("RIGHT", row=0, column=1)
  593. self.app.addLabel("title", "Cliente Multimedia P2P - Redes2 ")
  594. self.app.addImage("video", "imgs/webcam.gif")
  595.  
  596. self.app.startFrame("Botones llmada")
  597. self.app.addButtons(["Conectar","Conectar con","Pausar","Reanudar","Colgar"], [
  598. self.conectar,self.conectar_con,self.pausar,self.reanudar, self.colgar])
  599.  
  600.  
  601. self.app.addLabelOptionBox("Fuente Video", ["Webcam", "Fichero"])
  602. self.app.addNamedButton("SelectVideo", "Seleccionar Video", self.seleccionar_video)
  603. self.app.setOptionBoxChangeFunction("Fuente Video", self.cambiar_fuente_video);
  604. self.app.hideButton("Seleccionar Video")
  605.  
  606.  
  607. #self.app.hideButton("Pausar")
  608. self.app.stopFrame()
  609.  
  610. self.app.stopFrame()
  611.  
  612. # Ventana llamando
  613. self.app.startSubWindow("recibiendo")
  614. self.app.addLabel("popup", "")
  615. self.app.stopSubWindow()
  616. self.app.hideSubWindow("recibiendo")
  617.  
  618. # Añadir los botones
  619. self.app.addStatusbar(fields=2)
  620.  
  621. self.app.setStopFunction(self.quit)
  622.  
  623. def cambiar_estado(self, estado):
  624. if estado == "Registro":
  625. self.app.showFrame("Registro")
  626. self.app.hideFrame("LEFT")
  627. self.app.hideFrame("RIGHT")
  628.  
  629. self.app.setGeom("340x420")
  630.  
  631. self.estado = estado
  632. elif estado == "Default":
  633. self.app.setGeom("780x530")
  634. self.listar(None)
  635. self.app.hideFrame("Registro")
  636. self.app.showFrame("LEFT")
  637. self.app.showFrame("RIGHT")
  638. self.estado = estado
  639.  
  640. def registrarse(self, btn=None):
  641. nick = self.app.getEntry("Username")
  642. password = self.app.getEntry("Password")
  643.  
  644. if len(nick) == 0:
  645. return self.app.errorBox("Error Validación", "Nick no valido")
  646. elif len(password) == 0:
  647. return self.app.errorBox("Error Validación", "Password no valido")
  648.  
  649. user = self.server.register(
  650. nick, self.control.port, password)
  651. if user:
  652. user.save_to_file()
  653. self.cambiar_estado("Default")
  654. self.user = user
  655. self.app.setStatusbar("User: %s" % self.user.name, field=0)
  656. else:
  657. self.app.errorBox("Error Registro", "Contraseña incorrecta")
  658.  
  659. def cambiar_fuente_video(self, obj):
  660. valor = self.app.getOptionBox(obj)
  661. if valor == "Webcam":
  662. self.app.hideButton("Seleccionar Video")
  663. self.use_webcam=True
  664. else:
  665. self.app.showButton("Seleccionar Video")
  666. self.use_webcam=False
  667.  
  668. def seleccionar_video(self, btn=None):
  669. self.video_path = self.app.openBox("Seleccionar Video", None, fileTypes=[('video', '*.mp4')], asFile=False)
  670.  
  671.  
  672.  
  673. def logout(self, btn):
  674. self.cambiar_estado("Registro")
  675. self.app.setStatusbar("", 0)
  676. User.delete_user_file()
  677.  
  678. def conectar(self, button):
  679. # Entrada del nick del usuario a conectar
  680. nick = self.app.textBox("Conexión",
  681. "Introduce el nick del usuario a buscar")
  682.  
  683. if nick == self.user.name:
  684. self.app.errorBox("¡Error llamada!",
  685. "No te puedes llamar a ti mismo")
  686. else:
  687. user = self.server.query(nick)
  688.  
  689. self.user.udpport = self.udp_control.get_src_port()
  690.  
  691. if self.use_webcam:
  692. self.cap = cv2.VideoCapture(0)
  693. else:
  694. self.cap = cv2.VideoCapture(self.video_path)
  695.  
  696. result = self.control.llamar(self.user, user)
  697. if result:
  698. self.app.setLabel("popup", "Llamando a "+nick+"...")
  699. self.app.showSubWindow("recibiendo")
  700. #winsound.PlaySound("sounds/Phone_Ringing.wav", winsound.SND_LOOP + winsound.SND_ASYNC)
  701. else:
  702. self.app.errorBox("Usuario no conectado",
  703. "El usuario %s no está conectado" % user.name)
  704. def conectar_con(self):
  705. pass
  706.  
  707. def pausar(self, btn=None):
  708. self.control.call_hold()
  709. self.sending_video = False
  710. self.udp_control.queue_out.queue.clear()
  711. self.udp_control.queue_in.queue.clear()
  712.  
  713. def reanudar(self, btn=None):
  714. self.control.call_resume()
  715. self.sending_video=True
  716.  
  717. def colgar(self, btn):
  718. self.control.call_end(self.user.name)
  719. self.sending_video = False
  720. self.cap.release()
  721. self.udp_control.stop_threads = True
  722.  
  723. def recibiendo_call_end(self):
  724. self.sending_video = False
  725. self.cap.release()
  726. self.udp_control.stop_threads = True
  727.  
  728. def listar(self, button):
  729. users = self.server.list_users()
  730.  
  731. if users:
  732. users = sorted(users, key=lambda x: x.name.lower())
  733. self.user_list = users
  734. self.app.clearListBox("users_list")
  735. self.app.addListItems("users_list", list(
  736. map(lambda x: x.name, users)), select=False)
  737.  
  738. else:
  739. pass
  740.  
  741. def quit(self, btn=None):
  742. self.control.exit()
  743. return True
  744.  
  745. def start(self):
  746. self.app.go()
  747.  
  748. # Función que captura el frame a mostrar en cada momento
  749. def capturaVideo(self):
  750.  
  751.  
  752. if self.sending_video:
  753. # Capturamos un frame de la cámara o del vídeo
  754. ret, frame = self.cap.read()
  755. frame = cv2.resize(frame, (640, 480))
  756. cv2_im = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
  757. img_tk = ImageTk.PhotoImage(Image.fromarray(cv2_im))
  758.  
  759. # Compresión JPG al 50% de resolución (se puede variar)
  760. encode_param = [cv2.IMWRITE_JPEG_QUALITY, 50]
  761. result, encimg = cv2.imencode('.jpg', frame, encode_param)
  762.  
  763. if result == False:
  764. print('Error al codificar imagen')
  765. encimg = encimg.tobytes()
  766.  
  767.  
  768.  
  769. self.udp_control.queue_in.put(encimg)
  770. if not self.udp_control.queue_out.empty():
  771. img = self.udp_control.queue_out.get()
  772. # Descompresión de los datos, una vez recibidos
  773. decimg = cv2.imdecode(np.frombuffer(img,np.uint8), 1)
  774.  
  775. # Conversión de formato para su uso en el GUI
  776. cv2_im = cv2.cvtColor(decimg,cv2.COLOR_BGR2RGB)
  777. img_tk = ImageTk.PhotoImage(Image.fromarray(cv2_im))
  778.  
  779. # Lo mostramos en el GUI
  780. self.app.setImageData("video", img_tk, fmt='PhotoImage')
  781.  
  782. # Establece la resolución de la imagen capturada
  783. def setImageResolution(self, resolution):
  784. # Se establece la resolución de captura de la webcam
  785. # Puede añadirse algún valor superior si la cámara lo permite
  786. # pero no modificar estos
  787. if resolution == "LOW":
  788. self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 160)
  789. self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 120)
  790. elif resolution == "MEDIUM":
  791. self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
  792. self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
  793. elif resolution == "HIGH":
  794. self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
  795. self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
  796.  
  797. # Función que gestiona los callbacks de los botones
  798.  
  799. def buttonsCallback(self, button):
  800. if button == "Salir":
  801. # Salimos de la aplicación
  802. self.app.stop()
  803. elif button == "Conectar":
  804. self.app.showSubWindow("mihai")
  805.  
  806. def video_thread():
  807. UDP_IP = get_Host_name_IP()
  808. UDP_PORT = 6000
  809.  
  810. sock = socket.socket(socket.AF_INET, # Internet
  811. socket.SOCK_DGRAM) # UDP
  812. sock.bind((UDP_IP, UDP_PORT))
  813.  
  814. while True:
  815. data, addr = sock.recvfrom(8192) # buffer size is 1024 bytes
  816. img = data.split("#")
  817. decimg = cv2.imdecode(np.frombuffer(img[-1], np.uint8), 1)
  818. # Conversión de formato para su uso en el GUI
  819. cv2_im = cv2.cvtColor(decimg, cv2.COLOR_BGR2RGB)
  820. img_tk = ImageTk.PhotoImage(Image.fromarray(cv2_im))
  821. self.app.setImageData("video", img_tk, fmt='PhotoImage')
  822.  
  823. def manage_connection(self):
  824. print("HEYY there im using wpp")
  825. while 1:
  826. conn, addr = self.control_socket.accept()
  827. data = conn.recv(1024)
  828. print(data)
  829. rdata = data.decode("UTF-8").split(" ")
  830. if rdata[0] == "CALLING":
  831. f = open("last_user_reg.txt", "r")
  832. nick = f.read()
  833. f.close()
  834. self.port_dest = rdata[2]
  835. self.ip_dest = str(addr)
  836. self.sending_video = True
  837. self.frame_count = 0
  838.  
  839. edata = "CALL_ACCEPTED " + nick + " 8080"
  840. conn.send(edata.encode("utf-8"))
  841.  
  842.  
  843. def get_Host_name_IP():
  844. #return "127.0.0.1"
  845. try:
  846. host_name = socket.gethostname()
  847. host_ip = socket.gethostbyname(host_name)
  848. return host_ip
  849. except:
  850. raise Exception("Unable to get Hostname and IP")
  851.  
  852.  
  853. if __name__ == '__main__':
  854.  
  855. if len(sys.argv) == 2:
  856. User.filename = sys.argv[1]
  857.  
  858. vc = VideoClient("823x504")
  859.  
  860. # Crear aquí los threads de lectura, de recepción y,
  861. # en general, todo el código de inicialización que sea necesario
  862. # ...
  863.  
  864. # Lanza el bucle principal del GUI
  865. # El control ya NO vuelve de esta función, por lo que todas las
  866. # acciones deberán ser gestionadas desde callbacks y threads
  867. vc.start()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement