Проблема с методом transcribe библиотеки распознавание речи whisper

После запуска идёт запись голосового ввода в течении 5 секунд в файл "recorded_audio.wav" (находится в одной папке с проектом), далее идёт его распознавание.

import sounddevice as sd
import soundfile as sf
import whisper
from pathlib import Path

def record_audio():
    print("говорите")

    # Запись аудио
    audio_data = sd.rec(int(5 * 44100),
                        samplerate=44100,
                        channels=1,
                        dtype='float32')
    sd.wait()  # Ожидание окончания записи

    # Сохранение в файл
    sf.write("recorded_audio.wav", audio_data, samplerate=44100)
    print(f"Аудио сохранено как {"recorded_audio.wav"}")

def transcribe_audio():
    # Загрузка модели
    model = whisper.load_model("base")
    print(f"Модель загружена...")
    
    #путь к файлу
    path = Path("recorded_audio.wav").absolute()

    # Распознавание аудио
    result = model.transcribe(path, language="ru")
    return result["text"]

if __name__ == "__main__":
    record_audio()
    transcription = transcribe_audio()
    print(transcription) 

С записью аудио всё в порядке, но выходит следующая ошибка:

              
result = model.transcribe(path, language="ru")
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: expected np.ndarray (got WindowsPath)

Ответы (3 шт):

Автор решения: Vitalizzare ушел в монастырь

Ошибка, которую вы видите, обманчива в силу того, как построен код библиотеки whisper. Ожидается, что параметр audio это прежде всего объект Tensor библиотеки PyTorch, а если нет и он не строка, то предполагается, что это массив numpy.ndarray с аудиотреком в бинарном виде. Вы используете pathlib.Path, который не является подтипом str и не проходит проверку isinstance(audio, str). Поэтому программа работает с ним как с массивом ndarray, о чем и говорит TypeError: expected np.ndarray.

Исправляем ошибку либо приведением типа к строке, в данном случае str(path), либо самостоятельным чтением файла в массив NumPy.

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

Но вы можете выбрать и второй путь, поскольку sounddevice.rec возвращает запись в виде numpy.ndarray, которую можно использовать как аргумент для метода transcribe вашей модели. Понадобиться подогнать параметры. Прежде всего, выставить samplerate=16000 при записи. Это частота дискредитации, используемая в whisper по умолчанию, она хранится в константе whisper.audio.SAMPLE_RATE:

from whisper.audio import SAMPLE_RATE

def record_audio(file_path=None):
    print("Говорите...")
    audio_data = sd.rec(int(5 * SAMPLE_RATE),
                        samplerate=SAMPLE_RATE,
                        channels=1,
                        dtype='float32')
    sd.wait()  
    if file_path is not None:
        sf.write(file_path, audio_data, samplerate=SAMPLE_RATE)
        print(f"Аудио сохранено как {file_path}")
    return audio_data

def transcribe_audio(audio_data):
    model = whisper.load_model("base")
    print(f"Модель загружена...")
    if isinstance(audio_data, str) or isinstance(audio_data, Path):
        audio_data = str(Path(audio_data).absolute())
    result = model.transcribe(audio_data, language="ru")
    return result["text"]

if __name__ == "__main__":
    audio_data = record_audio()
    transcription = transcribe_audio(audio_data)
    print(transcription)
→ Ссылка
Автор решения: Alex
import sounddevice as sd
import soundfile as sf
import whisper
import numpy as np
from pathlib import Path

def record_audio():
    print("Говорите")

    # Запись аудио
    audio_data = sd.rec(int(5 * 44100),
                        samplerate=44100,
                        channels=1,
                        dtype='float32')
    sd.wait()  # Ожидание окончания записи

    # Сохранение в файл
    sf.write("recorded_audio.wav", audio_data, samplerate=44100)
    print(f"Аудио сохранено как recorded_audio.wav")

def transcribe_audio():
    # Загрузка модели
    model = whisper.load_model("base")
    print(f"Модель загружена...")

    # Путь к файлу
    path = Path("recorded_audio.wav").absolute()

    # Загрузка аудиофайла как массива данных
    audio_data, samplerate = sf.read(path)

    # Распознавание аудио
    result = model.transcribe(audio_data, language="ru")
    return result["text"]

if __name__ == "__main__":
    record_audio()
    transcription = transcribe_audio()
    print(transcription)
→ Ссылка
Автор решения: Человек Человеков

Всё можно было сделать намного проще. Изначально, я делал запись и распознавание с помощью всем известной SpeechRecognition. Однако, запись часто обрывалась на шипящих и глухих звуках. Например(речь пользователя- что распознал код): влад ветлужских - влад, красная площадь - краз, роман степанов - роман и т.д. Я подумал, что можно переписать запись голоса, а распознавание оставить на SR. Получилось!

import sounddevice as sd
import soundfile as sf
import speech_recognition as sr

def record_audio():
    print("говорите")

    # Запись аудио
    audio_data = sd.rec(int(5 * 16000),
                        samplerate=16000,
                        channels=1,
                        dtype='float32')
    sd.wait()  # Ожидание окончания записи

    # Сохранение в файл
    sf.write("recorded_audio.wav", audio_data, samplerate=16000)
    print(f"Аудио сохранено как recorded_audio.wav")
    return "recorded_audio.wav"

def transcribe_audio():
    with sr.AudioFile("recorded_audio.wav") as source:
        audio = recognizer.record(source)  # Чтение аудиофайла
        try:
            recognized_data = recognizer.recognize_google(audio, language="ru-RU").lower()
            print("Распознанный текст: " + recognized_data)
            return recognized_data
        except sr.UnknownValueError:
            print("Речь не распознана")

if __name__ == "__main__":
    micro = sr.Microphone()
    recognizer = sr.Recognizer()

    record_audio()
    transcribe_audio()
→ Ссылка