# -*-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()