| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- # -*-coding:Latin-1 -*
- """fonction client du chat vocal (protocole UDP)"""
- from socket import socket, AF_INET, SOCK_DGRAM
- from time import sleep
- from threading import Thread
- from os import system
- import logging
- #modules complémentaires
- import pymedia.audio.sound as sound
- import pymedia.audio.acodec as acodec
- from pyaudio import PyAudio, paInt16
- #modules perso
- from anason import AnaSon
- from lecture import Lecture
- #gestion des erreurs et log
- logging.basicConfig(level=logging.DEBUG)
- logCVoc = logging.getLogger(__name__)
- handlerCVoc = logging.FileHandler('chatVoc.log')
- handlerCVoc.setFormatter(logging.Formatter('[%(asctime)s] %(levelname)s - %(message)s')) #%(name)s - nom du module
- logCVoc.addHandler(handlerCVoc)
- logCVoc.debug(" ---------------------- \n")
- port = 6660
- frequence = 22050
- #param d'encodage/decodage
- cparams= { 'id': acodec.getCodecID( 'mp3' ),
- 'bitrate': 32000,
- 'sample_rate': frequence,
- 'channels': 1 }
- taille_paquets = 1024
- debug = False
- ######### Fils secondaires #########
- class ReceptionVoc(Thread):
- """fil gerant la reception du son"""
- def __init__(self, cnn):
- """création du fil reception"""
- self.connecte = True
- Thread.__init__(self)
- self.cnn = cnn
- self.essais = 0
- self.connectes = {}
-
- def run(self):
- """reception: tourne en boucle tant que la connexion est active"""
- while self.connecte:
- try:
- fr, adresse = self.cnn.recvfrom(taille_paquets)
- #print("recu {}".format(len(fr)))
- #les 2 premiers caracteres sont le pseudo de l'expediteur
- expediteur = fr[:2]
- donnee = fr[2:]
- if not expediteur in self.connectes.keys():
- #nouveau connecte
- try:
- fil = Lecture(expediteur, cparams, debug)
- fil.start()
- self.connectes[expediteur] = fil
- logCVoc.info("\n -> Connecte a {}".format(expediteur))
- except KeyboardInterrupt:
- logCVoc.error("{} - Erreur de reception".format(expediteur))
- else:
- if donnee:
- self.connectes[expediteur].lire(donnee)
-
- self.essais = 0
- except IOError, e:
- if e.errno == 10022:
- sleep(0.001)
- self.essais += 1
- if self.essais == 1000:
- logCVoc.warning("pas de reception")
- self.essais = 0
-
- def stop(self):
- """Fermeture du fil Reception"""
- logCVoc.info("\nChat vocal : Reception interrompue")
- for fil in self.connectes.values():
- fil.stop()
- self.connecte = False
- self.cnn.close()
-
-
- #fin du fil reception
- #objet client:
- class ClientVoc(Thread):
- """client pour le chat vocal"""
- def __init__(self, idClient, ipServeur, port):
- """création du client"""
- Thread.__init__(self)
- self.idClient = idClient
- self.ipServeur = ipServeur
- self.port = 6660
-
- ###parametrage du socket udp###
- self.cnn = socket(AF_INET, SOCK_DGRAM)
- self.connecte = False
- #flux microphone:
- self.stream = PyAudio().open(format = paInt16,
- channels = 1,
- rate = frequence,
- input = True,
- frames_per_buffer = 1024)
- #encodage:
- self.ac = acodec.Encoder( cparams )
-
- #traitement du son?
- self.traitement = False
- if self.traitement:
- #parametres de traitement du son:
- self.ana = AnaSon()
- #on recupere les parametres enregistres si possible
- self.ana = self.ana.recup()
-
- def creer(self):
- """demarre une instance client pour le chat vocal"""
- if len(self.idClient) == 2 and len(self.ipServeur) > 0 :
- self.thR = ReceptionVoc(self.cnn)
- self.thR.start()
- self.connecte = True
- self.start()
- txt = "Chat vocal demarre"
- logCVoc.info(txt)
- else:
- txt = "Chat vocal : erreur dans les parametres d'entree"
- logCVoc.error(txt)
- return txt
- def run(self):
- """emission: tourne en boucle tant que la connexion est active"""
- #on affiche les parametres du micro
- if self.traitement:
- logCVoc.info(self.ana)
-
- while self.connecte:
- #son = micro.getData()
- son = self.stream.read(1024)
- if son and len(son):
- if self.traitement:
- son = self.ana.traitement(son)
-
- if son:
- son_encode = self.ac.encode(son)
-
- for fr in son_encode:
- if len(fr) < (taille_paquets - 2):
- #on ajoute l'id du client au debut du paquet
- envoi = self.idClient + fr
- #print("envoi {}".format(len(fr)))
- self.cnn.sendto(envoi, (self.ipServeur, port))
- else:
- logCVoc.warning("1 paquet trop volumineux")
- else:
- #si pas de son, on attend un peu
- sleep(0.003)
- def stop(self):
- """quitte la session de chat"""
- if self.connecte:
- self.thR.stop()
- self.stream.close()
- self.cnn.close()
- txt = "Fermeture du chat vocal"
- logCVoc.info(txt)
- return txt
-
- ### fil principal ###
- if __name__ == "__main__":
- # si lancement direct:
- idClient = raw_input("id client (2car)")
- c = ClientVoc(idClient, "localhost", 6660)
- c.creer()
- system("pause")
- c.stop()
|