5

您好,我遇到了一个无法解决的 PyAudio 问题。当我通过网络使用它时(一段时间后)它崩溃了。我得到的错误是

线程 Thread-1 中的异常:
回溯(最近一次通话最后):
  文件“C:\Python27\lib\threading.py”,第 552 行,在 __bootstrap_inner
    自我运行()
  运行中的文件“C:\Python27\lib\threading.py”,第 505 行
    self.__target(*self.__args, **self.__kwargs)
  服务器中的文件“C:\Users\maboroshi\Desktop\myChat\chat.py”,第 71 行
    frames_per_buffer = 块)
  文件“C:\Python27\lib\site-packages\pyaudio.py”,第 714 行,打开
    流 = 流(自我,*args,**kwargs)
  __init__ 中的文件“C:\Python27\lib\site-packages\pyaudio.py”,第 396 行
    self._stream = pa.open(**参数)
IOError: [Errno 设备不可用] -9985

我的代码在下面(大部分:-P

这是用于解密数据和管理连接

def decrypt_my_message(味精):
    iv = "1234567812345678"
    键 = your_friends_key
    如果 len(key) 不在 (16, 24, 32) 中:
        raise ValueError("Key 必须是 16、24 或 32 字节")
    如果 (len(msg) % 16) != 0:
        raise ValueError("消息必须是 16 字节的倍数")
    如果 len(iv) != 16:
        raise ValueError("IV 必须是 16 字节")
    密码 = AES.new(密钥,AES.MODE_CBC,iv)
    明文 = cipher.decrypt(msg)
    返回明文

### 服务器功能###
定义服务器():
    主机 = ''
    端口 = 9001
    ### 初始化套接字
    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)
    ### 开始接收循环
    read_list = [server_socket]
    而真:
        可读,可写,错误 = select.select(read_list, [], [])
        对于 s 可读:
            如果 s 是 server_socket:
                连接,地址 = s.accept()
                read_list.append(conn)
                打印“连接自”,地址
            别的:
                味精 = conn.recv(2024)
                如果味精:                
                    命令,味精= ord(味精[0]),味精[1:]
                    如果 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()
                        流 = p.open(格式 = 格式,
                                        频道 = 频道,
                                        率 = 率,
                                        输入=真,
                                        输出=真,
                                        frames_per_buffer = 块)
                        stream.write(decrypt_my_message(msg), chunk) #将数据写回扬声器
                别的:
                    s.close()
                    read_list.remove(s)

这是用于连接和发送加密音频

def encrypt_my_audio_message(msg):
    键 = 你的键
    iv = '1234567812345678'
    aes = AES.new(key, AES.MODE_CBC, iv)
    编码器 = PKCS7Encoder()
    pad_text = encoder.encode(msg)
    msg = aes.encrypt(pad_text)
    返回消息

定义连接服务器():
    客户端口 = 9001
    CLIENT_HOST = str(entryhost.get())
    全球
    尝试:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((CLIENT_HOST, CLIENT_PORT))
        打印“已连接\n”
    除了:
        打印“无法连接”

### 客户端功能###        
定义客户端(cmd,味精):
    尝试:
        s.send(cmd + msg)
    除了:
        打印“您未连接”

默认发送音频():
    p = pyaudio.PyAudio()
    流 = p.open(格式 = 格式,
                    频道 = 频道,
                    率 = 率,
                    输入=真,
                    输出=真,
                    frames_per_buffer = 块)
    数据 = 流。读取(块)
    返回 encrypt_my_audio_message(数据)
## stream.stop_stream()
## stream.close()
## p.terminate()

def 按键(事件):
    如果 event.keysym == 'Escape':
        root.destroy()
    #x = event.char
    如果 event.keysym == 'Control_L':
        #print("发送数据...")
        客户端(chr(CMD_AUDIO),sendAudio())
        #print("数据已发送!")

发生这种情况的任何想法都将是最有帮助的

4

2 回答 2

0

让我大吃一惊的是你正在混合一个阻塞的线程与 select 的线程,并且循环看起来有点奇怪。你在两个方向都有很多事情要做——试着专注于让数据包的流入和流出就像齿轮啮合一样工作,或者确保有人在他们的时候不会是空的或满的。预计两者都不是。

您可能会从以下方面找到一些灵感:

于 2011-12-09T04:07:21.260 回答
0

我的猜测是您遇到了问题,因为您正在创建多个 PyAudio 对象并打开多个流而不关闭它们中的任何一个。

您应该创建一个 PyAudio 对象和一个流,然后重新使用这些对象。

于 2012-08-09T02:12:56.423 回答