File size: 8,449 Bytes
595cff0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

import speech_recognition as sr
from pydub import AudioSegment
import os
import gradio as gr
import types
import typing
import logging


logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s')


def convert_wav_to_text(audio_file_path: str) -> str:
    """
    Эта функция получает на вход файл, который который представляет собой аудио. Если формат .wav, то такой файл сразу распознаётся.
    А если формат отличается от .wav, то такой аудиофайл сначала конвертируется во временное представление .wav, распознаётся и удаляется.

    Args:
        audio_file_path (Str): Путь к файлу-голосовому сообщению.
    Returns:
        text_from_audio (Str): Текст, полученный из голосового сообщения.
        error (Str): Сообщение об ошибке.
    """
    file_extension = audio_file_path.split('.')[-1].lower()                                         #получаем формат файла
    try:                                                                                            #блок для отлова возможных ошибок
        if file_extension != 'wav':                                                                 #если формат не .wav
            audio = AudioSegment.from_file(audio_file_path, format=file_extension)                  #загружаем аудиофайл с указанием его формата
            audio = audio.set_channels(1).set_frame_rate(16000)                                     #преобразуем аудио в моно (1 канал) и устанавливаем частоту дискретизации 16000 герц (необходимо для улучшения качества распознавания речи)
            temp_wav_path = 'temp.wav'                                                              #определяем временный путь для сохранения преорбазованногоаудиофайла в формате .wav
            audio.export(temp_wav_path, format='wav')                                               #экспортируем преобразованное аудио в формат .wav и сохраняем по временному пути
        else:                                                                                       #иначе
            temp_wav_path = audio_file_path                                                         #просто сохраняем аудиофайл
        recognizer = sr.Recognizer()                                                                #создаём объект-распознаватель речи
        with sr.AudioFile(temp_wav_path) as source:                                                 #открываем аудиофайл
            audio_data = recognizer.record(source)                                                  #и записываем его содержимое
            try:                                                                                    #блок для отлова возможных ошибок
                text_from_audio = recognizer.recognize_google(audio_data, language='ru-RU')         #пробуем преобразовать данные аудиофайла с помощью сервисов Google
                return text_from_audio                                                              #возвращаем полученный текст
            except sr.UnknownValueError:                                                            #если ошибка связана с речью или шумом
                error_str = 'Не удалось распознать аудио! Возможно, в данных слишком много шума.'   #то создаём сообщение-ошибку
                return error_str                                                                    #и печатаем его
            except sr.RequestError as e:                                                            #если ошибка при запросе
                error_str = f'Возникла неожиданная ошибка: {e}'                                     #то создаём сообщение-ошибку
                return error_str                                                                    #и печатаем его
    finally:                                                                                        #этот блок выполняется независимо от наличия ошибок
        if file_extension != 'wav' and os.path.exists('temp.wav'):                                  #если есть воеменный файл temp.wav (который создаётся для перезаписывания аудиофайла)
            os.remove('temp.wav')                                                                   #то удаляем этот файл


def recognize_speech_from_microphone(audio: typing.Union[str, types.NoneType, AudioSegment]) -> str:
    """
    Функция, которая записывает аудио.

    Args:
        audio (Str): Путь к аудиофайлу (загруженный файл).
        audio (types.NoneType): Появляется при смене типа входных данных.
        audio (AudioSegment): При записи звука микрофоном.
    Return:
        text_from_audio (Str): Результат выполнения функции convert_wav_to_text().
        warning_str (Str): Предупреждение при смене типа входных данных.
    """
    if isinstance(audio, str):                                                                   #если входящие данные - путь к файлу (а не записанный звук с микрофона)
        audio_file_path = audio                                                                  #то сразу передаём путь без экспорта
    elif isinstance(audio, types.NoneType):                                                      #если входящие данные без типа (пользователь кликнул по смене типа входящих данных)
        warning_str = 'Вы изменили источник входных данных. Запишите звук или загрузите файл.'   #то создаём сообщение-предупреждение
        return warning_str                                                                       #и печатаем его
    else:                                                                                        #иначе (пользователь записывает звук микрофоном)
        audio_file_path = 'temp_input.wav'                                                       #задаём имя файлу
        audio.export(audio_file_path, format='wav')                                              #конвертируем в .wav-формат
    return convert_wav_to_text(audio_file_path)                                                  #передаём в функцию-распознаватель


gui = gr.Interface(                        #создаём пользовательский интерфейс gradio
    fn=recognize_speech_from_microphone,   #функция, которая вызывается при записи аудио
    inputs=gr.Audio(type='filepath'),      #входной компонент для записи аудио с микрофона устройства
    outputs='text',                        #выходной компонент для отображения текста
    live=True                              #позволяет запускаться и работать в реальном времени
)


if __name__ == '__main__':
    gui.launch(share=True)   #запускаем страницу и локально, и публично