如何在Python中读取.wav字节流

12

有没有一种方法可以读取.wav格式二进制数据的帧?我正在将.wav二进制数据流式传输到Python服务器,我希望能够从pyaudio处理中读取和使用它,但是pyaudio会抱怨帧大小。

由于我不能使用wave.open('filename.wav'),因为我已经有了正在流式传输的二进制数据,是否有一种方法可以读取二进制数据,以便我可以在 Python库中使用readframes方法?

编辑: 我尝试从客户端流式传输readframes,但是pyaudio会出现错误,说字节不是.wav格式。 但如果我能在服务器上完成这项工作,那就太理想了。


你是指 getnframes 还是 readframes?我在文档中没有看到 getframes - user3657941
读取帧,抱歉造成困惑。我尝试从客户端流式传输readframes,但是pyaudio会报错,指出字节不在.wav格式中。然而,如果可以在服务器端完成这个操作,那就太理想了。 - user7993435
你可以创建一个包含wave所需的所有file方法的对象,并将其传递给wave.open函数:"如果文件是字符串,则按照该名称打开文件,否则将其视为可寻址的类文件对象。" - user3657941
你的二进制流中包含什么?是整个WAV文件的内容,包括头部,还是只有纯粹的音频样本?如果是后者,你可以直接将字节传递给PyAudio,你只需要确保传递正确数量的数据,并告诉PyAudio正确的数据类型和通道数。顺便说一句,PyAudio不知道WAV文件,我很确定它在错误消息中也没有提到它们。你应该提供实际的错误消息! - Matthias
3个回答

3
from scipy.io import wavfile
fs, data = wavfile.read('your file path')

3

正如@Vishesh Mangla所指出的那样,使用librosa是处理音频信号的一个很棒的库。

import librosa

sr = librosa.get_samplerate('/path/to/file.wav')

# Set the frame parameters to be equivalent to the librosa defaults
# in the file's native sampling rate
frame_length = (2048 * sr) // 22050
hop_length = (512 * sr) // 22050

# Stream the data, working on 128 frames at a time
stream = librosa.stream('path/to/file.wav',
                        block_length=128,
                        frame_length=frame_length,
                        hop_length=hop_length)

chromas = []
for y in stream:
   chroma_block = librosa.feature.chroma_stft(y=y, sr=sr,
                                              n_fft=frame_length,
                                              hop_length=hop_length,
                                              center=False)
   chromas.append(chromas)

在这个例子中,每个音频片段 y 都由 128 帧样本组成,更具体地说,len(y) == frame_length + (block_length - 1) * hop_length。每个片段 y 将与后续片段重叠 frame_length - hop_length 个样本,这确保了流处理将提供与整个序列一步处理相同的结果(假设禁用了填充/居中)。有关流接口的更多详细信息,请参阅 librosa.core.stream

0
回应自己的悬赏,有一个优雅的解决方案,我从这个与获取虚拟文件对象相关的更一般的语境中借鉴了链接1
import io
audio = wave.open(io.BytesIO(bytes))

这将启用 wave 的所有 API,至少是我用于与原始问题相同情景的子集,适用于 Python 字节对象。例如,使用上面的 audio 变量,现在可以执行以下操作:
format=self.audio.get_format_from_width(
   audio.getsampwidth()),
   channels=audio.getnchannels(),
   rate=audio.getframerate(),
   frames_per_buffer=self.chunk_size,
   output=True)

由于波浪库似乎仅支持磁盘文件对象,因此这是一个不错的解决方法,至少它依赖于标准的Python库(io),该库提供了我们在API中需要的东西。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接