clientvoc.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. # -*-coding:Latin-1 -*
  2. """fonction client du chat vocal (protocole UDP)"""
  3. from socket import socket, AF_INET, SOCK_DGRAM
  4. from time import sleep
  5. from threading import Thread
  6. from os import system
  7. import logging
  8. #modules complémentaires
  9. import pymedia.audio.sound as sound
  10. import pymedia.audio.acodec as acodec
  11. from pyaudio import PyAudio, paInt16
  12. #modules perso
  13. from anason import AnaSon
  14. from lecture import Lecture
  15. #gestion des erreurs et log
  16. logging.basicConfig(level=logging.DEBUG)
  17. logCVoc = logging.getLogger(__name__)
  18. handlerCVoc = logging.FileHandler('chatVoc.log')
  19. handlerCVoc.setFormatter(logging.Formatter('[%(asctime)s] %(levelname)s - %(message)s')) #%(name)s - nom du module
  20. logCVoc.addHandler(handlerCVoc)
  21. logCVoc.debug(" ---------------------- \n")
  22. port = 6660
  23. frequence = 22050
  24. #param d'encodage/decodage
  25. cparams= { 'id': acodec.getCodecID( 'mp3' ),
  26. 'bitrate': 32000,
  27. 'sample_rate': frequence,
  28. 'channels': 1 }
  29. taille_paquets = 1024
  30. debug = False
  31. ######### Fils secondaires #########
  32. class ReceptionVoc(Thread):
  33. """fil gerant la reception du son"""
  34. def __init__(self, cnn):
  35. """création du fil reception"""
  36. self.connecte = True
  37. Thread.__init__(self)
  38. self.cnn = cnn
  39. self.essais = 0
  40. self.connectes = {}
  41. def run(self):
  42. """reception: tourne en boucle tant que la connexion est active"""
  43. while self.connecte:
  44. try:
  45. fr, adresse = self.cnn.recvfrom(taille_paquets)
  46. #print("recu {}".format(len(fr)))
  47. #les 2 premiers caracteres sont le pseudo de l'expediteur
  48. expediteur = fr[:2]
  49. donnee = fr[2:]
  50. if not expediteur in self.connectes.keys():
  51. #nouveau connecte
  52. try:
  53. fil = Lecture(expediteur, cparams, debug)
  54. fil.start()
  55. self.connectes[expediteur] = fil
  56. logCVoc.info("\n -> Connecte a {}".format(expediteur))
  57. except KeyboardInterrupt:
  58. logCVoc.error("{} - Erreur de reception".format(expediteur))
  59. else:
  60. if donnee:
  61. self.connectes[expediteur].lire(donnee)
  62. self.essais = 0
  63. except IOError, e:
  64. if e.errno == 10022:
  65. sleep(0.001)
  66. self.essais += 1
  67. if self.essais == 1000:
  68. logCVoc.warning("pas de reception")
  69. self.essais = 0
  70. def stop(self):
  71. """Fermeture du fil Reception"""
  72. logCVoc.info("\nChat vocal : Reception interrompue")
  73. for fil in self.connectes.values():
  74. fil.stop()
  75. self.connecte = False
  76. self.cnn.close()
  77. #fin du fil reception
  78. #objet client:
  79. class ClientVoc(Thread):
  80. """client pour le chat vocal"""
  81. def __init__(self, idClient, ipServeur, port):
  82. """création du client"""
  83. Thread.__init__(self)
  84. self.idClient = idClient
  85. self.ipServeur = ipServeur
  86. self.port = 6660
  87. ###parametrage du socket udp###
  88. self.cnn = socket(AF_INET, SOCK_DGRAM)
  89. self.connecte = False
  90. #flux microphone:
  91. self.stream = PyAudio().open(format = paInt16,
  92. channels = 1,
  93. rate = frequence,
  94. input = True,
  95. frames_per_buffer = 1024)
  96. #encodage:
  97. self.ac = acodec.Encoder( cparams )
  98. #traitement du son?
  99. self.traitement = False
  100. if self.traitement:
  101. #parametres de traitement du son:
  102. self.ana = AnaSon()
  103. #on recupere les parametres enregistres si possible
  104. self.ana = self.ana.recup()
  105. def creer(self):
  106. """demarre une instance client pour le chat vocal"""
  107. if len(self.idClient) == 2 and len(self.ipServeur) > 0 :
  108. self.thR = ReceptionVoc(self.cnn)
  109. self.thR.start()
  110. self.connecte = True
  111. self.start()
  112. txt = "Chat vocal demarre"
  113. logCVoc.info(txt)
  114. else:
  115. txt = "Chat vocal : erreur dans les parametres d'entree"
  116. logCVoc.error(txt)
  117. return txt
  118. def run(self):
  119. """emission: tourne en boucle tant que la connexion est active"""
  120. #on affiche les parametres du micro
  121. if self.traitement:
  122. logCVoc.info(self.ana)
  123. while self.connecte:
  124. #son = micro.getData()
  125. son = self.stream.read(1024)
  126. if son and len(son):
  127. if self.traitement:
  128. son = self.ana.traitement(son)
  129. if son:
  130. son_encode = self.ac.encode(son)
  131. for fr in son_encode:
  132. if len(fr) < (taille_paquets - 2):
  133. #on ajoute l'id du client au debut du paquet
  134. envoi = self.idClient + fr
  135. #print("envoi {}".format(len(fr)))
  136. self.cnn.sendto(envoi, (self.ipServeur, port))
  137. else:
  138. logCVoc.warning("1 paquet trop volumineux")
  139. else:
  140. #si pas de son, on attend un peu
  141. sleep(0.003)
  142. def stop(self):
  143. """quitte la session de chat"""
  144. if self.connecte:
  145. self.thR.stop()
  146. self.stream.close()
  147. self.cnn.close()
  148. txt = "Fermeture du chat vocal"
  149. logCVoc.info(txt)
  150. return txt
  151. ### fil principal ###
  152. if __name__ == "__main__":
  153. # si lancement direct:
  154. idClient = raw_input("id client (2car)")
  155. c = ClientVoc(idClient, "localhost", 6660)
  156. c.creer()
  157. system("pause")
  158. c.stop()