在Python中合并.wav文件而无需将其写入磁盘

5

我有一个二进制格式的.wav文件列表(这些文件来自websocket),我想把它们合并成一个单一的二进制.wav文件,然后对其进行语音识别。我已经使用以下代码使其正常工作:

audio = [binary_wav1, binary_wav2,..., binary_wavN] # a list of .wav binary files coming from a socket
audio = [io.BytesIO(x) for x in audio]

# Join wav files
with wave.open('/tmp/input.wav', 'wb') as temp_input:
    params_set = False
    for audio_file in audio:
        with wave.open(audio_file, 'rb') as w:
            if not params_set:
                temp_input.setparams(w.getparams())
                params_set = True
            temp_input.writeframes(w.readframes(w.getnframes()))

# Do speech recognition
binary_audio = open('/tmp/input.wav', 'rb').read())
ASR(binary_audio)

问题在于我不想在磁盘上写入文件'/tmp/input.wav'。有没有任何方法可以在不在磁盘上写入任何文件的情况下完成此操作?
谢谢。

当声音为单声道时,可以将其表示为1D数组,而立体声则为2D。使用类似于“wavefile”的工具获取原始数据。 - Josef Korbel
1
wave.open 可以接受文件路径或类文件对象。由于您已经导入了 BytesIO,因此只需将其中一种用作文件缓冲区即可。这里有一个人用 gzip 做了基本上相同的事情(注意略有不同的参数名称)。 - Aaron
2个回答

6

如果需要拥有一个文件但不想将其存储在磁盘上,一般的解决方案是使用流。对此,我们使用了io库,这是默认用于处理内存流的库。看起来您之前的代码中甚至已经使用了BytesIO

audio = [binary_wav1, binary_wav2,..., binary_wavN] # a list of .wav binary files coming from a socket
audio = [io.BytesIO(x) for x in audio]

# Join wav files

params_set = False
temp_file = io.BytesIO()
with wave.open(temp_file, 'wb') as temp_input:
    for audio_file in audio:
        with wave.open(audio_file, 'rb') as w:
            if not params_set:
                temp_input.setparams(w.getparams())
                params_set = True
            temp_input.writeframes(w.readframes(w.getnframes()))

#move the cursor back to the beginning of the "file"
temp_file.seek(0)
# Do speech recognition
binary_audio = temp_file.read()
ASR(binary_audio)

注意 我没有任何.wav文件可以尝试此操作。这取决于wave库是否能够正确处理真实文件和缓冲流之间的差异。


谢谢,这个有效!我之前尝试过,但是我漏掉了temp_file.seek(0)语句,所以我只读取了一个空的二进制对象。 - Iñigo Casanueva

0
使用scipy和numpy,您可以将wav文件读取为numpy数组,然后进行所需的修改。
from scipy.io import wavfile
import numpy as np

# load files
_, arr1 = wavfile.read('song.wav')
_, arr2 = wavfile.read('Aaron_Copland-Quiet_City.wav')

print(arr1.shape)
print(arr2.shape)

>>> (1323001,)
>>> (1323000,)

# make new array by concatenating two audio waves
new_arr = np.hstack((arr1, arr2))
print(new_arr.shape)

>>> (2646001,)

# save new audio wave
wavfile.write('new_audio.wav')

这个方法可以实现,但引入scipy和/或numpy似乎有些浪费。正如@Aaron在他的回答中指出的,您可以简单地像BytesIO那样写入类文件对象。 - Samuel Dion-Girardeau

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