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

Posted

技术标签:

【中文标题】使用一个 pyaudio 流进行数据读取和写入【英文标题】:Using one pyaudio stream for both data reading and writing 【发布时间】:2019-01-14 14:20:08 【问题描述】:

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

【问题讨论】:

【参考方案1】:

没有理由创建两个流。 在同一个流回调函数中读写是完全没问题的。 只需在“非阻塞”模式下创建流(即通过指定回调函数)。

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

也没有必要创建单独的线程。如果您使用带有回调函数的 PyAudio 流,该函数会在单独的线程中自动调用(由底层 PortAudio 库自动创建)。

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

【讨论】:

【参考方案2】:

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

回答

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

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

我现在正在使用 PyAudio,流式传输非常有趣,但从编程的角度来看很难理解。实际上,您可以在耳机中创建 2 个输出流,并在通往耳机的途中的某个硬件中的某个位置,这些流会自行汇总,因此您可以同时收听两种声音。

注意:

另外我想说你不必担心使用线程。流以批处理方式工作,而不是实时工作。无论是读取还是写入,它的工作方式是,您将二进制数据推送到流中,然后就完成了。硬件接受二进制数据,流式传输它们,只有在完成后,流才会请求另一个数据。因此,如果您有 sample_rate 44100 和块 22050(只是示例),您的循环将只有 0.5 秒。因此,您甚至不必担心溢出、需要处理的数据过多或线程变得疯狂。 事实上,当您将数据推送到流式传输时,您的 python 会等待您的硬件完成工作。它非常轻巧。

【讨论】:

我的客户端已经有了两个流,一个用于输入,一个用于输出。但我正在努力寻找实现 pyaudio 数据“交换”的最佳方式。我的逻辑是“越少越好”,因为它更容易维护,更轻计算机。因此,我想也许一个多功能流会更好。 我不是 PyAudio 方面的专家,但我确信你不能从编程的角度考虑这个问题。这是更多的硬件问题。检查我添加到答案的注释 好吧,我给了你我的两分钱,但就我而言,我看到你的问题有两条高速公路。从你到他,从他到你。我不会把它混合在一起。每条高速公路一个方向 感谢您的帮助

以上是关于使用一个 pyaudio 流进行数据读取和写入的主要内容,如果未能解决你的问题,请参考以下文章

C# - 将数据写入流 + 使用另一个流读取数据

java IO使用Java输入输出流 读取txt文件内数据,进行拼接后写入到另一个文件中

将数据作为原始数据读取和写入流?

pyaudio录音不写文件

java 中简述使用流进行读写文本文件的步骤?

Java使用PipedStream管道流通信