Создать и использовать WAV-файл как объект Python - PullRequest
0 голосов
/ 08 апреля 2020

Я создаю личного помощника в Python. Я использую Snowboy для записи аудио, и это работает очень хорошо. У Snowboy есть метод saveMessage (), который создает и записывает файл wav на диск. Этот файл wav позже читается и используется в качестве объекта AudioFile Speech_Recognition. Я считаю очень неэффективным, что программа должна записывать и читать файлы 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 требует, чтобы в него был передан путь к волновому файлу ИЛИ к файлообразному объекту. Я не уверен, что такое «подобный файлу» объект, поэтому я предоставлю оператор assert AudioFile для аргумента файла wav:

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

Я использую python 3.7 на Raspberry PI 3B + с Raspbian Buster Lite версии 4.19. 36.

Если я могу предоставить какую-либо дополнительную информацию или уточнить что-либо, пожалуйста, спросите.

Большое спасибо!

1 Ответ

1 голос
/ 08 апреля 2020

Примерно так должно работать:

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 может вызывать снежного человека изнутри, поэтому вам, вероятно, не нужно использовать внешний снежный человек, вы можете просто использовать listen с параметром snowboy_configuration .

...