PyAudio和缓冲区溢出

1 投票
1 回答
1477 浏览
提问于 2025-04-18 08:34

我正在尝试使用pyaudio来播放流式音频。

我获取了一些数据,处理这些数据,然后把它们放到音频流里。

数据的传输速度基本上是稳定的,只是有点波动。

从日志中我可以看到,数据传输速度是稳定的,而且处理速度也是实时的。

Demodulation ended after 0.0877389907837 seconds
demodulation tooked  0.0463800430298 seconds
Data is coming with period -0.150208950043 seconds

我有0.150秒的音频数据,而我处理这些数据只用了0.08秒。

在播放器程序的日志中,我看到一开始一切正常。实际播放数据的时间基本上和预期的一样(比如150毫秒)。但是过了一段时间,这个播放时间就变短了,我开始看到缓冲区溢出的错误。这就像是数据没有及时到达一样。但从日志来看,数据处理还是实时的。所以我不知道为什么会出现这种情况。

这是我为多进程音频播放器写的代码。

class MultiprocessedAudioPlayer(object):

    def __init__(self, sampling_frequency, min_buffer_size=1, max_buffer_size=10, sample_width=2):
        self.p = PyAudio()
        self.stream = self.p.open(format=self.p.get_format_from_width(width=sample_width), rate=sampling_frequency,
                                  output=True, channels=1)
        self.sub = ZmqSubscriber(host='tcp://localhost', port='8888', on_receive_callback=self.on_frame_received)
        self.buffer = deque(maxlen=max_buffer_size)

    def on_frame_received(self, frame):
        self.play(blosc.unpack_array(frame[0]))

    def play(self, frame):
        print('started playing frame at {}'.format(datetime.now()))
        print('frame length is {}'.format(len(frame)))
        self.stream.write(frame, num_frames=len(frame))
        print('stopped playing frame at {}'.format(datetime.now()))

    def close(self):
        self.stream.stop_stream()
        self.stream.close()
        self.p.terminate()

1 个回答

1

你的问题听起来跟我之前在使用pyaudio的阻塞模式播放音频时遇到的情况很像。

我播放音频的时候,也出现了在音频还没播放完之前就结束了的情况。我怀疑是我提供的音频数据比pyaudio播放的速度快,所以导致了这个问题。我在阻塞模式下一直没能解决这个问题。

我解决这个问题的方法是使用回调函数,而不是继续使用阻塞模式。

如果你想看看怎么做,可以参考这个链接:这里

撰写回答