Распознавание речи в Telegram «на лету»

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

Задача распознавания голосовых сообщений в Telegram уже давно не новая. На эту тему написано много статей, разработано немало Telegram-ботов. С некоторыми решениями я ознакомился во время работы над функцией распознавания голосовых напоминаний для бота @RemindMegaBot и заметил, что в этих решениях используется не всегда оправданный подход:

Для распознавания речи аудиофайл загружается на диск.

Возникает справедливый вопрос — неужели нельзя обойтись без записи файла на диск? Ведь это освободит операционную систему от лишних операций и сократит время обработки данных!

Почему же разработчики используют именно такой подход?

Дело в том, что голосовые сообщения в Telegram записываются в ogg-формате и кодируются opus-кодеком. Наиболее популярные сервисы распознавания голоса не поддерживают этот формат (или кодек), поэтому приходится его преобразовывать в .wav, .mp3 или даже в тот же .ogg, но использовать уже vorbis-кодек. Для этого авторы решений рекомендуют использовать ffmpeg, который, в свою очередь, требует сохранения аудио-файлов на диск.

Но использовать ffmpeg необязательно. Есть альтернативные решения, которые позволяют декодировать opus-данные. Ниже я приведу одно из таких решений, реализованное на языке Go.

В нашем примере будем подключаться к сервису распознавания речи wit.ai. Сервис wit.ai поддерживает формат "audio/raw". Для декодирования голосового сообщения Telegram будем использовать библиотеку opus. Для работы с API wit.ai будем использовать официальную библиотеку wit-go.

Общий алгоритм функции распознавания речи выглядит прозрачно:

func Recognize(fileDirectURL string) (string, error) {
    // 1. Получаем содержимое аудиофайла по ссылке
    fileBody, err := getFileBody(fileDirectURL)
    if err != nil {
        return "", err
    }
    // 2. Преобразовываем данные в формат audio/raw
    audioRawBuffer, err := getAudioRawBuffer(fileBody)
    if err != nil {
        return "", err
    }
    // 3. Распознаем голосовое сообщение		
    client := witai.NewClient("YOUR_WIT_AI_TOKEN")
    msg, err := client.Speech(&witai.MessageRequest{
        Speech: &witai.Speech{
            File:        audioRawBuffer,
            ContentType: "audio/raw;encoding=signed-integer;bits=16;rate=48000;endian=little",
        },
    })
    if err != nil {
        return "", err
    }

    return msg.Text, nil
}

Содержимое аудиофайла получаем с использованием стандартных библиотек:

func getFileBody(fileDirectURL string) ([]byte, error) {
    resp, err := http.Get(fileDirectURL)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()
    fileBody, err := io.ReadAll(resp.Body)
    if err != nil {
        return nil, err
    }
    return fileBody, nil
}

Opus-данные декодируем по инструкции, выложенной разработчиками библиотеки.

func getAudioRawBuffer(fileBody []byte) (*bytes.Buffer, error) {
    channels := 1
    s, err := opus.NewStream(bytes.NewReader(fileBody))
    if err != nil {
        return nil, err
    }
    defer s.Close()

    audioRawBuffer := new(bytes.Buffer)
    pcmbuf := make([]int16, 16384)
    for {
        n, err := s.Read(pcmbuf)
        if err == io.EOF {
            break
        } else if err != nil {
            return nil, err
        }
        pcm := pcmbuf[:n*channels]
        err = binary.Write(audioRawBuffer, binary.LittleEndian, pcm)
        if err != nil {
            return nil, err
        }
    }
    return audioRawBuffer, nil
}

После этого содержимое буфера пересылаем в wit.ai и получаем распознанный текст.

На этом пока всё. Спасибо за внимание!

Источник: https://habr.com/ru/post/587442/


Интересные статьи

Интересные статьи

В основном, про Firebase рассказывают в контексте создания приложений под IOS или Android. Однако, данный инструмент можно использовать и в других областях разработки, на...
Существует традиция, долго и дорого разрабатывать интернет-магазин. :-) Лакировать все детали, придумывать, внедрять и полировать «фишечки» и делать это все до открытия магазина.
Сиамская нейросеть — один из простейших и наиболее популярных алгоритмов однократного обучения. Методики, при которой для каждого класса берётся лишь по одному учебному примеру. Таким образом...
Привет Хабр. В процессе изучения нейронных сетей возникла мысль, как бы применить их для чего-то практически интересного, и не столь заезженного и тривиального, как готовые датасеты от MNIST. ...
Довольно часто владельцы сайтов просят поставить на свои проекты индикаторы курсов валют и их динамику. Можно воспользоваться готовыми информерами, но они не всегда позволяют должным образом настроить...