Использование речевых технологий Яндекса на примере аудиосообщений Telegram или чат-бот для распознавания аудиосообщений
В данной статье мы рассмотрим применение речевых технологий, предоставленных компанией #яндекс в контексте распознавания аудиосообщений в Telegram – популярном мессенджере, объединяющем миллионы пользователей по всему миру.
Получилось довольно интересно:
Данный функционал нам великодушно и альтруистично (почти) предоставила компания Яндекс на их сервисе Яндекс. Облако (Yandex. Cloud). На первый взгляд, название может напоминать о неком облачном хранилище для бесконечных потоков фотографий с телефона, но на самом деле все куда интереснее:
Яндекс. Облако — это сервис облачных вычислений, предоставляемый компанией Яндекс. Он позволяет людям и компаниям арендовать виртуальные серверы и ресурсы для хранения данных, запуска приложений и выполнения вычислений через интернет. Это как аренда виртуального пространства на компьютерах компании Яндекс, чтобы использовать их мощности для своих целей без необходимости покупки и поддержки собственного оборудования.
На Яндекс. Облаке можно найти кучу различных программистских интересностей — распознавание/генерация аудио, машинный перевод, нейросети, базы данных и т. д. Полный список актуальных решений можно посмотреть здесь или посмотреть их список, взятый из википедии ниже:
Да, каждый сервис платный, но их стоимость, в большинстве решений, не столь высока, да и Яндекс предоставляет тестовый период и грант для новых пользователей. Подробные условия их получения можно посмотреть здесь и здесь. Говоря кратко — если вы только зарегистрировались в Яндекс. Облаке, то нате 2 месяца бесплатного доступа, чтобы все затестить.
Театр начинается с вешалки
Переходим на Яндекс. Облако, авторизируемся и попадаем в консоль. После чего сразу создаем здесь платежный аккаунт. Если вы вошли сюда в первый раз, то получаем пробный период/грант или не заморачиваемся и пополняем счет на пару десятков рублей, привязав банковскую карту.
Следующее, что нам нужно сделать — это создать сервисный аккаунт. Сервисный аккаунт в Яндекс. Облаке — это как виртуальная личность для программы или сервиса, которую можно создать, чтобы позволить ей использовать ресурсы и функции облачных серверов без необходимости использовать личный аккаунт. Это позволяет приложениям и программам работать в облаке, делая их доступ более безопасным и удобным, и изолируя их от других пользователей.
Для этого переходим на данную вкладку:
Далее в данном разделе жмем на кнопку «Создать сервисный аккаунт». Вводим название и выбираем роль. В данном примере мы будем использовать функционал по распознавания аудио — Speech-To-Text (STT), поэтому в качестве роли выберем «ai. speechkit-stt. user».
Жмем «Создать« и после недолгой прогрузки увидим новую строку в списке сервисных аккаунтов на этой же странице. Нажимаем на эту строчку и попадаем на новую страницу, где в правой верхней части экрана находим кнопку «Создать новый ключ», нажимаем и выбираем »API-ключ». Появится форма, в которой можно задать описание для данного ключа — нажимаем «Создать» и получаем свежий ключ:
Готово! Сохраняем себе данный ключ или не закрываем данную форму, чтобы потом его скопировать в программу.
Заключаем сделку с BotFather
Чтобы затестить функционал сервиса давайте соберем простейшего чат-бота для Telegram, который будет расшифровывать аудиосообщения и присылать нам текст.
Для начала пойдем к BotFather и, склонив колено, попросим токен для нового чат-бота:
- Запускаем бота BotFather
- Вызываем команду /newbot
- Вводим название для нового бота
- Вводим его username
- Получаем токен
Теперь перейдем к основной части представления и начнем писать код чат-бота.
Тык тык тык делаю по клавишам
Для создания чат-бота воспользуемся библиотекой telebot (или pyTelegramBotAPI), которую установим таким образом:
Сперва создадим файл «config. py», где будем хранить все полученные ключи и экземпляр класса TeleBot (импортированный из библиотеки telebot), с помощью которого будут происходить все взаимодействия с чат-ботом. В конструктор данного класса передаем лишь только токен, который мы до этого получили и сохранили в переменную BOT_TOKEN.
Заменяем значения переменных BOT_TOKEN и YC_STT_API_KEY на свой токен и API-ключ соответственно. Далее создаем файл «main. py», где будет располагаться функционал самого чат-бота. В начале определим все импорты:
Здесь мы импортировали объект класса TeleBot из раннее созданного «config. py» и класс Message из подмодуля types библиотеки. Данный класс представляет собой сообщение, отправленное в чат и содержит всю исчерпывающую информацию о нем.
Первое, что должен уметь чат-бот — это реагировать на команду /start, которая как раз и вызывается при запуске бота:
Здесь мы использовали декоратор из объекта bot, который даст нашей программе знать, что вот эту функцию start нужно вызывать только тогда, когда пользователь ввел команду /start.
Самая функция принимает лишь один аргумент — это экземпляр класса Message, то есть, в данном случае, это будет то самое сообщение с командой /start, которую юзер отправил сам или просто нажал «Запустить», войдя первый раз в нашего бота. В последнем случае она будет отправлена за него боту автоматически.
message_handler — это декоратор из библиотеки telebot, предназначенный для обработки входящих сообщений в чат-боте. Он позволяет задать функцию, которая будет вызываться автоматически, когда бот получает сообщение определенного типа или удовлетворяющее определенным условиям.
В самом конце файла размещаем следующий код, который запустит бот при запуске «main. py»:
Итак, теперь наш бот реагирует на его запуск пользователем и выпрашивает аудиосообщение:
Раз уж просит, то давайте дадим ему такую возможность и напишем еще одну функцию которая будет реагировать на отправку голосового сообщения:
Сперва определим функцию с другим декоратором, который будет реагировать уже не на команду, а тип сообщения — а именно голосовое:
Давайте импортируем еще один класс из библиотеки, который будет представлять аудиосообщение:
Теперь внутри функции нам нужно получить отправленное/пересланное аудиосообщение. Так как оно уже хранится на серверах Telegram, то мы можем просто получить путь к нему:
В данном случае переменная voice_path будет храниться в себе относительный путь к аудиофайлу, например: «voice/file_0.oga». То есть, есть сервер Telegram, а в нем директория со всеми файлами нашего бота — там есть папка voice где и лежит присланное аудиосообщение.
OGA — это расширение файла аудио, используемое на серверах Telegram. Этот формат, известный как Ogg Vorbis, обеспечивает хорошее качество звука и небольшие размеры файлов, что позволяет передавать голосовые сообщения в мессенджере с высокой четкостью и экономией трафика.
Однако, толку от такого пути для нас никакого. Давайте применим немного хитрости и получим абсолютный путь к сохраненному аудиосообщению. Для этого нам понадобится токен бота, который мы сохранили в «config. py»:
И относительный путь файла, хранящийся в переменной voice_path:
Таким образом мы получим абсолютный путь к аудиофайлу на сервере Telegram вида:
https://api. telegram. org/file/botxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/voice/file_0.oga
Теперь у нас есть ссылка на аудиофайл и мы можем отправить ее Яндекс. Облаку, который попытается получить из данного аудиофайла текст.
Путешествие аудиосообщения
Создаем еще один файл, где мы будем взаимодействовать с сервисом Yandex. Cloud. Назовем его, к примеру «yandex_cloud. py». Мы могли бы использовать какие-нибудь готовые библиотеки для данной задачи, но для такого простого функционала легче написать взаимодействие при помощи классического модуля requests. Импортируем его и API-ключ от Яндекс. Облака из конфига:
Определим переменную с адресом, на который будет идти запрос:
И создаем функцию, которая будет принимать в качестве аргумента адрес аудиофайла на серверах Telegram и возвращать распознанный из него текст:
Осталось только доработать функцию handle_voice из «main. py»
Осталось совсем чуть-чуть
Вернемся к модулю main и импортируем созданную функцию:
Продолжим код функции handle_voice и добавим пару строчек:
Снова запускаем бота и, смотрим на результат:
Готово!
Полный код бота можно скачать на GitHub: