使用一个pyaudio流进行数据读取和写入

时间:2019-01-14 14:20:08

标签: python audio audio-streaming pyaudio

我有一个Web套接字客户端,该客户端在请求中发送音频二进制数据,并从Web套接字服务器接收它们作为响应。我正在使用pyaudio从(文件/麦克风)读取二进制音频数据,然后将其发送到服务器。然后,作为响应,我从服务器收到另一个二进制音频数据。问题是我可以使用最近打开的pyaudio阅读流实时播放接收音频,还是更好地创建另一个pyaudio流(有两个流,其中一个负责二进制数据读取,另一个负责二进制数据写入)?

2 个答案:

答案 0 :(得分:1)

请注意一个事实,据我所知,读取流数据是一种生成器过程。一旦读取,就会丢失数据-换句话说:基于块,基本上,每次“读取”都会移动一个捕获二进制数据的指针。

答案

为什么不创建带有2个流的2个线程?不要害怕溪流。您可以根据需要初始化任意数量。

  • 1个线程接收二进制数据并将其推送到流中(从客户端到您的声音设备)
  • 2个线程从您的输入流(从麦克风以二进制形式)接收数据,然后将其推送到客户端?

我现在正在与PyAudio一起工作,流媒体虽然很有趣,但是从编程的角度来看很难理解。实际上,您可以在耳机中创建2个输出流,并在通往耳机的途中的某个硬件中的某个位置将这些流汇总在一起,以便您可以轻松地同时收听两种声音。

注意:

我也想说,您不必担心使用线程。流是批量工作的,不是实时的。无论是读取还是写入,它都以某种方式工作,即您具有二进制数据,可以将其推送到流中并完成操作。硬件接受二进制数据,对其进行流传输,并且只有在完成后,流才会要求其他数据。因此,如果您有sample_rate 44100和块22050(仅作为示例),则循环将仅为0.5s。因此,您甚至不必担心溢出,太多数据无法处理或线程变得疯狂。 实际上,当您将数据推送到流中时,您的python等待您的硬件完成工作。它非常轻巧。

答案 1 :(得分:1)

没有理由创建两个流。 在同一个流回调函数中进行读写是非常好的。 只需以“非阻塞”模式创建流(即通过指定回调函数)。

您只需要确保使用足够大的缓冲区,以防某些时候网络连接花费的时间比平均时间长一点。 您应该使用某种队列在线程之间移动数据,例如queue.Queue来自Python的标准库。

也不必创建单独的线程。如果您将PyAudio流与回调函数一起使用,则会在一个单独的线程中自动调用该函数(该线程由基础PortAudio库自动创建)。

话虽如此,如果您出于某些其他原因需要它们,您当然可以创建多个流。另外,如果需要,您可以 创建线程。