开发者

PyAudio Over Network crashes

开发者 https://www.devze.com 2023-03-18 04:32 出处:网络
Hello I am facing an issue with PyAudio I can not solve. When I use it over the network (after a while) it crashes. The error I get is

Hello I am facing an issue with PyAudio I can not solve. When I use it over the network (after a while) it crashes. The error I get is

Exception in thread Thread-1:
Traceback (most recent call last):
  File "C:\Python27\lib\threading.py", line 552, in __bootstrap_inner
 开发者_运维技巧   self.run()
  File "C:\Python27\lib\threading.py", line 505, in run
    self.__target(*self.__args, **self.__kwargs)
  File "C:\Users\maboroshi\Desktop\myChat\chat.py", line 71, in server
    frames_per_buffer = chunk)
  File "C:\Python27\lib\site-packages\pyaudio.py", line 714, in open
    stream = Stream(self, *args, **kwargs)
  File "C:\Python27\lib\site-packages\pyaudio.py", line 396, in __init__
    self._stream = pa.open(**arguments)
IOError: [Errno Device unavailable] -9985

My code is below (well most of it :-P

This is for decrypting the data and managing connections

def decrypt_my_message(msg):
    iv = "1234567812345678"
    key = your_friends_key
    if len(key) not in (16, 24, 32):
        raise ValueError("Key must be 16, 24, or 32 bytes")
    if (len(msg) % 16) != 0:
        raise ValueError("Message must be a multiple of 16 bytes")
    if len(iv) != 16:
        raise ValueError("IV must be 16 bytes")
    cipher = AES.new(key, AES.MODE_CBC, iv)
    plaintext = cipher.decrypt(msg)
    return plaintext

### Server function ###
def server():
    HOST = ''
    PORT = 9001
    ### Initialize socket 
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_socket.bind((HOST, PORT))
    server_socket.listen(5)
    ### Start recieve loop
    read_list = [server_socket]
    while True:
        readable, writable, errored = select.select(read_list, [], [])
        for s in readable:
            if s is server_socket:
                conn, addr = s.accept()
                read_list.append(conn)
                print "Connection from ", addr
            else:
                msg = conn.recv(2024)
                if msg:                
                    cmd, msg = ord(msg[0]),msg[1:]
                    if cmd == CMD_MSG:
                        listb1.insert(END, decrypt_my_message(msg.strip()) + "\n")
                        listb1.yview(END)
                    elif cmd == CMD_AUDIO:
                        #d = speex.Decoder()
                        #d.initialize(speex.SPEEX_MODEID_WB)
                        p = pyaudio.PyAudio()
                        stream = p.open(format = FORMAT,
                                        channels = CHANNELS,
                                        rate = RATE,
                                        input = True,
                                        output = True,
                                        frames_per_buffer = chunk)
                        stream.write(decrypt_my_message(msg), chunk)    #Write the data back out to the speakers
                else:
                    s.close()
                    read_list.remove(s)

And this is for connecting and sending encrypted audio

def encrypt_my_audio_message(msg):
    key = your_key
    iv = '1234567812345678'
    aes = AES.new(key, AES.MODE_CBC, iv)
    encoder = PKCS7Encoder()
    pad_text = encoder.encode(msg)
    msg = aes.encrypt(pad_text)
    return msg

def connectToServer():
    CLIENT_PORT = 9001
    CLIENT_HOST = str(entryhost.get())
    global s
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((CLIENT_HOST, CLIENT_PORT))
        print "Connected\n"
    except:
        print "Could not connect"

### Client Function ###        
def client(cmd, msg):
    try:
        s.send(cmd + msg)
    except:
        print "You are not connected"

def sendAudio():
    p = pyaudio.PyAudio()
    stream = p.open(format = FORMAT,
                    channels = CHANNELS,
                    rate = RATE,
                    input = True,
                    output = True,
                    frames_per_buffer = chunk)
    data = stream.read(chunk)
    return encrypt_my_audio_message(data)
##    stream.stop_stream()
##    stream.close()
##    p.terminate()

def keypress(event):
    if event.keysym == 'Escape':
        root.destroy()
    #x = event.char
    if event.keysym == 'Control_L':
        #print("Sending Data...")
        client(chr(CMD_AUDIO), sendAudio())
        #print("Data Sent!")

Any ideas why this happens would be most helpful


The thing that jumps out at me is that you're mixing a thread that blocks with select, and the loop looks a bit weird. You've got a lot of stuff going on in both directions - try and focus on making the flow of packets in and out work like gears meshing together, or ensure that there's no way that somebody is going to be empty or full when they're expected to be neither.

You might find some inspiration from:

  • this portaudio/speex python wrapper
  • asyncore
  • queue


My guess is that you're running into problems because you are creating multiple PyAudio objects and opening multiple streams without closing any of them.

You should create one PyAudio object, and one stream, and re-use those objects.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号