Преобразование байтов файла WAV в формат, совместимый с распознаванием речи - PullRequest
3 голосов
/ 23 апреля 2020

Я три дня бьюсь головой о стену на конвейере автоматизации Python, который принимает двоичный байтовый массив вложений электронной почты .WAV (например, b'RIFFm \ xc1 \ x00 \ x00WAVEfmt [...] ') телефонная система автоматически отправляет sh через какой-либо текст-речевой API, например speech_recognition, или через какую-нибудь будущую реализацию Sphinx / Kaldi в автономном режиме, и отправляет стенограмму обратно. В идеале все это должно обрабатываться в памяти без необходимости создавать файлы на диске, так как это кажется излишним, но я пытаюсь выяснить, что Python можно переместить из аудиоданных, которые у меня есть, в транскрипт, который я могу отправить, и я не против небольшая очистка файла.

Проблема, с которой я сталкиваюсь, заключается в том, что вложения файлов .WAV, которые я вручную загружал для тестирования, и двоичные данные, с которыми я работаю с помощью API электронной почты, плохо работают с * 1004. * Зависимость с wave.open('ipsum.wav') дает Error: unknown format: 49 и работа с библиотекой speech_recognition заканчивается тем, что ошибка wave неизвестного формата преобразуется в ValueError: Audio file could not be read as PCM WAV, AIFF/AIFF-C, or Native FLAC; check if file is corrupted or in another format.

Конвертирование локальных файлов, которые у меня есть, вручную .wavs, использующий онлайн-инструмент для преобразования файлов, похоже, решает проблему таким образом, с которым speech_recognition готов работать, и мне удалось получить рабочую стенограмму, выполняющую это (стенограмма была слишком короткой для файла, но это отдельная порция) выпуск). Таким образом, проблема, похоже, заключается в том, что wave не устраивает то, как файлы, которые отправляет мне телефонная система, форматируются / кодируются / сжимаются, и решение лежит где-то в репликации того, как этот инструмент веб-преобразования кодировал эти тестовые файлы.

Я возился с функцией pydub .export(), чтобы попытаться заставить ее преобразовать во что-то wave лайки (pydub удалось воспроизвести эти файлы), но, похоже, я попал в круг и я возвращаюсь туда, где я начал с отслеживания ошибок, обсужденных выше. Идеальное решение, вероятно, заключается в каком-то инструменте, который манипулирует байтовым массивом вложений электронной почты в памяти, но, опять же, я открыт для любых предложений Pythoni c.

Я могу изменить текст в речь фреймворк, который я использую от Google, где-то в дальнейшем, но код для меня уже есть для моей реализации basi c:

from exchangelib import Message
import io
import pydub
import speech_recognition as sr

r = sr.Recognizer()
def speech_to_text(Message):
    for attachment in Message.attachments:
        if attachment.content_type == 'audio/x-wav':
            content = attachment.content # Store attachment's binary data as a variable
            bytes = io.BytesIO(content) # Encode IO as bytes
            f= pydub.AudioSegment.from_file(bytes).export(attachment.name[:-4] +'.wav', format='wav') # Use bytes to create pydub's AudioSegment object
                                                                                                        # and export it as desired format
            with sr.AudioFile(f) as source: # Feed converted file into speech_recognition's AudioFile
                audio = r.record(source)
                transcript = r.recognize_google(audio)
                return transcript

Если у вас есть хорошие ресурсы или курсы, которые могут научить меня аудио преобразование файлов в стиле Pythoni c (я боролся с большим разрывом между очень практичными ресурсами, которые предполагают, что ваша обработка звука работает отлично, и чрезвычайно трудоемким обсуждением), я более чем рад их услышать.

1 Ответ

2 голосов
/ 25 апреля 2020

Стандартный библиотечный волновой модуль поддерживает только кодирование PCM, о чем свидетельствует этот код :

if wFormatTag == WAVE_FORMAT_PCM:
    try:
        ...
    else:
raise Error('unknown format: %r' % (wFormatTag,))

То, с чем вы имеете дело, это 8,000 Hz GSM 06.10, или, чаще, GSM. Подробнее о различных схемах кодирования вы можете прочитать в wiki .

Свидетельства от soxi :

soxi msg0000\ \(2\).WAV 

Input File     : 'msg0000 (2).WAV'
Channels       : 1
Sample Rate    : 8000
Precision      : 16-bit
Duration       : 00:00:07.96 = 63680 samples ~ 597 CDDA sectors
File Size      : 13.0k
Bit Rate       : 13.1k
Sample Encoding: GSM

Решение

Используйте любую библиотеку, которая поддерживает кодирование GSM. soundfile - отличный выбор; многие популярные аудио модули используют его под.

import soundfile as sf

sf.read('msg0000 (2).WAV') 

Выход:

(array([0.00024414, 0.        , 0.        , ..., 0.00048828, 0.00048828,
        0.00024414]),
 8000)
...