2

您好,我在通过网络发送音频时遇到问题。在我没有距离的本地系统上没有问题,但是每当我在远程系统上测试时,都会有音频,但不是语音输入,我想要它的断断续续/滞后等。我相信它是我处理音频发送的方式,但是我现在已经尝试了 4 天,但找不到解决方案。

我将发布所有相关代码并尽我所能解释它

这些是常量/全局值

    #initilaize Speex
    speex_enc = speex.Encoder()
    speex_enc.initialize(speex.SPEEX_MODEID_WB)
    speex_dec = speex.Decoder()
    speex_dec.initialize(speex.SPEEX_MODEID_WB)

    #一些常量值
    块 = 320
    格式 = pyaudio.paInt16
    频道 = 1
    速率 = 44100

我发现调整采样率值会产生更多噪音

下面是初始化音频设备的 pyAudio 代码,这也是全局的

    #initialize PyAudio
    p = pyaudio.PyAudio()
    流 = p.open(格式 = 格式,
                    频道 = 频道,
                    率 = 率,
                    输入=真,
                    输出=真,
                    frames_per_buffer = 块)

下一个功能是按键功能,它从麦克风写入数据并使用客户端功能发送它这是我认为我遇到问题的地方。

我相信我是如何处理这个问题的,因为如果我按住以获取音频,它会在每次迭代时循环并发送。我不确定在这里做什么。(想法!!!)

    def 按键(事件):
        #块列表 = []
        #RECORD_SECONDS = 5
        如果 event.keysym == 'Escape':
            root.destroy()
        #x = event.char
        如果 event.keysym == 'Control_L':   
            #for i in range(0, 44100 / chunk * RECORD_SECONDS):
            尝试:
                #从麦克风获取数据
                数据 = 流。读取(块)
            除了 IOError 作为 ex:
                如果 ex[1] != pyaudio.paInputOverflowed:
                    增加
                数据 = '\x00' * 块
            encda​​ta = speex_enc.encode(data) #对数据进行编码。
            #chunklist.append(encda​​ta)
            #发送音频
            客户端(chr(CMD_AUDIO),encrypt_my_audio_message(encda​​ta))

处理音频的服务器代码

    ### 服务器功能###
    定义服务器():
        端口 = 9001
        ### 初始化套接字
        server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        server_socket.bind((socket.gethostbyname(socket.gethostname()), PORT))
        # socket.gethostbyname(socket.gethostname())
        server_socket.listen(5)
        read_list = [server_socket]
        ### 开始接收循环
        而真:
            可读,可写,错误 = select.select(read_list, [], [])
            对于 s 可读:
                如果 s 是 server_socket:
                    连接,地址 = s.accept()
                    read_list.append(conn)
                    打印“连接自”,地址
                别的:
                    味精 = conn.recv(2048)
                    如果味精:                
                        命令,味精= ord(味精[0]),味精[1:]
                        ## 从 GUI 获取文本消息
                        如果 cmd == CMD_MSG:
                            listb1.insert(END, decrypt_my_message(msg).strip() + "\n")
                            listb1.yview(END)
                        ## 获取音频消息
                        elif cmd == CMD_AUDIO:
                            # 确保长度为 16 --- HACK ---
                            如果 len(msg) % 16 != 0:
                                味精 += '\x00' * (16 - len(味精) % 16)
                            #解密音频
                            数据 = decrypt_my_message(msg)
                            decdata = speex_dec.decode(数据)
                            #将数据写回扬声器
                            stream.write(decdata,块)
                    别的:
                        s.close()
                        read_list.remove(s)

并在 Tkinter 中完成键盘的绑定

    root.bind_all('', keypress)

任何想法都非常感谢我如何使按键方法根据需要工作或提出更好的方法,或者我可能完全做错了什么

*干杯

请注意,我已经在没有加密方法的情况下对其进行了测试,同样的事情:-)

4

1 回答 1

0

您是否运行 ping 或 ttcp 来测试两台主机之间的网络性能?

如果您有延迟峰值或某些数据包被丢弃,您发送语音流的方法将受到严重影响。TCP 将等待丢失的数据包,报告丢失,等待重传等。

您应该在有损链接和音频压缩上使用 UDP 来优雅地处理丢失的数据包。同样在这种情况下,您必须为传出的数据包加上时间戳。

于 2012-10-27T17:25:17.863 回答