Проблема с методом 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 шт):
Ошибка, которую вы видите, обманчива в силу того, как построен код библиотеки 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)
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()