创建并使用 WAV 文件作为对象 Python

Posted

技术标签:

【中文标题】创建并使用 WAV 文件作为对象 Python【英文标题】:Create and use WAV file as an object Python 【发布时间】:2020-04-07 23:31:24 【问题描述】:

我正在用 Python 创建一个个人助理。我正在使用 Snowboy 录制音频,效果很好。 Snowboy 有一个 saveMessage() 方法,可以创建一个 wav 文件并将其写入磁盘。此 wav 文件稍后会被 Speech_Recognition 读取并用作 AudioFile 对象。我发现程序必须将 wav 文件写入和读取到磁盘的效率非常低。我宁愿将 wav 文件作为对象传递,而无需将其保存到磁盘。

这里是我想重温的snowboy saveMessage() 模块。

def saveMessage(self):
    """
    Save the message stored in self.recordedData to a timestamped file.
    """
    filename = 'output' + str(int(time.time())) + '.wav'
    data = b''.join(self.recordedData)

    #use wave to save data
    wf = wave.open(filename, 'wb')
    wf.setnchannels(1)
    wf.setsampwidth(self.audio.get_sample_size(
        self.audio.get_format_from_width(
            self.detector.BitsPerSample() / 8)))
    wf.setframerate(self.detector.SampleRate())
    wf.writeframes(data)
    wf.close()
    logger.debug("finished saving: " + filename)
    return filename #INSTEAD OF RETURNING filename I WANT THIS TO RETURN THE wav file object

请注意,AudioFile 类要求必须将波形文件的路径或“类文件”对象传递给它。我不确定什么是“类文件”对象,所以我将为 wav 文件参数提供 AudioFile 断言语句:

assert isinstance(filename_or_fileobject, (type(""), type(u""))) or hasattr(filename_or_fileobject, "read"), "Given audio file must be a filename string or a file-like object"

我尝试使用 BytesIO 的实例来保存 wav 数据,BytesIO 显然不是类文件对象。这是我尝试过的:

def saveMessage(self):
    filename = 'output' + str(int(time.time())) + '.wav'
    data = b''.join(self.recordedData)

    #use wave to save data
    with io.BytesIO() as wav_file:
        wav_writer = wave.open(wav_file, "wb")
        try:
            wav_writer.setnchannels(1)
            wav_writer.setsampwidth(self.audio.get_sample_size(
                self.audio.get_format_from_width(
                    self.detector.BitsPerSample() / 8)))
            wav_writer.setframerate(self.detector.SampleRate())
            wav_writer.writeframes(data)
            wav_data = wav_file.getvalue()
        finally:
            wav_writer.close()
            logger.debug("finished saving: " + filename)
    return wav_data

我得到的错误是:AssertionError: Given audio file must be a filename string or a file-like object

我在运行 Raspbian Buster Lite 内核版本 4.19.36 的 Raspberry PI 3B+ 上使用 python 3.7。

如果我可以提供任何其他信息或澄清任何事情,请询问。

非常感谢!

【问题讨论】:

【参考方案1】:

这样的事情应该可以工作:

from speech_recognition import AudioData

def saveMessage(self):
    filename = 'output' + str(int(time.time())) + '.wav'
    data = b''.join(self.recordedData)
    ad = AudioData(data, 16000, 2)
    result = recognizer.recognize_google(ad)

请注意,speech_recognition.listen 可以在内部调用 snowboy,因此您可能不必使用外部 snowboy,只需使用参数 snowboy_configuration 的侦听即可。

【讨论】:

效果很好!对于任何从事与我类似的项目的人,我只是简单地修补了雪人的 saveMessage 方法以返回数据,然后使用数据创建了一个 AudioData 对象(就像 Nikolay 所做的那样)。然后我将该 AudioData 对象传递给 Speech_recognizer 的 identify_google 函数以获得我的输出。

以上是关于创建并使用 WAV 文件作为对象 Python的主要内容,如果未能解决你的问题,请参考以下文章

ffmpeg:如何将 wav 作为音频输入来创建视频?

使用 C 绕过声音/音频文件 (WAV)

python读取wav文件并播放[pyaudio/wave]

Python/Django - 我可以创建多个类似 pdf 文件的对象,将它们压缩并作为附件发送吗?

是否可以从 .wav 文件创建 MediaStream?

读取音频 wav 文件并绘制在 python 中平滑的音频频率响应