Учимся использовать API сервиса Yandex SpeechKit
После прочтения статьи вы сможете:
- разобраться, что же такое API на простых примерах (macOS);
- познакомиться с сервисом распознавания и синтеза речи от Yandex;
- сделаете своего первого голосового ассистента-дворецкого.
Подготовимся. Настройка профиля CLI
Активация аккаунта на облаке
Для использования сервиса YSK у вас должна быть почта на Yandex. Если у вас её нет, то самое время завести.
Будьте готовы к тому, что вам потребуется еще подтвердить свой номер мобильного телефона. Без этого, увы, сервисы будут недоступны.
Почта есть. Теперь самое время перейти на cloud.yandex.ru. Перейдя в консоль надо активировать пробный период пользования сервисом. Для этого надо привязать платежную карту. Как только вы это сделаете вам будет доступен грант на 60 дней.
В облака – через командную строку
Для понимания, как работает распознавание и синтез, мы потренируемся в командной строке. Например, в iTerm.
Для отправки запросов на API через командную строку установим утилиту cURL. Перед установкой проверьте, возможно, она у вас уже есть ($ curl --version):
$ brew install curl
Теперь настроим Интерфейс Яндекс.Облака для командной строки (CLI). Запустим скрипт:
$ curl https://storage.yandexcloud.net/yandexcloud-yc/install.sh | bash
Перезапустите командную оболочку. В переменную окружения PATH добавится путь к исполняемому файлу – install.sh.
Теперь нам нужно, чтобы в CLI заработало автодополнение команд в bash:
Если у вас еще нет менеджера пакетов Homebrew, установите его. Он вам не раз пригодится, обещаю.
Затем ставим пакет bash-completion:
$ brew install bash-completion
и посмотрим, что изменилось в файле ~/.bash_profile:
$ open ~/.bash_profile
Примечание: ~/.bash_profile используется для пользовательских настроек, в частности – для определения переменных окружения.
Видим, что в конце bash_profile добавились новые строчки:
.
.
# The next line updates PATH for Yandex Cloud CLI.
...
# The next line enables shell command completion for yc.
...
Выше новых строк вставьте эту:
if [ -f $(brew --prefix)/etc/bash_completion ]; then
. $(brew --prefix)/etc/bash_completion
fi
# Эти строчки - наш финальный этап для работы автодополнения команд в CLI. Здесь мы проверяем есть ли файл, который за это отвечает. И, если он есть (а он у нас уже есть) - он запускается.
Порядок! А теперь пристегнитесь, приступаем к инициализации и получаем наш первый “ключик”.
В пункте 1 вам предложат перейти по ссылке, и в отдельном окне появится aouth_token. Сохраните его себе или не закрывайте пока эту страницу.
Набираем команду:
$ yc init
и получаем приветственное сообщение:
Welcome! This command will take you through the configuration process.
Pick desired action:
[1] Re-initialize this profile 'default' with new settings
[2] Create a new profile
Please enter your numeric choice:
# профиль пока нас устраивает, поэтому выбирайте 1
Вам предложат выбрать облако (скорее всего у вас оно единственное):
You have one cloud available: 'cloud' (id = <цифры_и_буквы_вашей_папки>).
It is going to be used by default.
Please choose folder to use:
[1] default (id = <цифры_и_буквы_вашей_папки>)
[2] Create a new folder
# новая папка нам пока ни к чему :)
Далее по желанию выберете Compute zone. Пока пользователь один – этим можно пренебречь.
Посмотрим, как выглядят настройки профиля CLI:
$ yc config list
token: AgAAAAAAHzS2AATuwTpDlcC9LExto-7iIHEWH9o
cloud-id: b1gthramkv9de6i2ll5n
folder-id: b1gdt133kktmm89lr51l
compute-default-zone: ru-central1-b
Мы в шаге от старта. Осталось добыть второй ключ (в настройках профиля он не будет отображаться):
$ yc iam create-token
# приготовьтесь, будет много символов
Полетели!
Знакомство с API Yandex SpeechKit
Представьте простую, максимально идеальную ситуацию без подводных камней типа “а если..”. Вы организуете закрытую вечеринку и хотите общаться с гостями, ни на что не отвлекаясь. Тем более на тех, кого вы не ждали.
Давайте попробуем создать виртуального дворецкого, который будет встречать гостей и открывать дверь только приглашенным.
Синтез текста через cURL
С помощью встроенной в bash команды export запишем данные в переменные:
$ export FOLDER_ID=b1gvmob95yysaplct532
$ export IAM_TOKEN=CggaATEVAgA…
Теперь их можно передать в POST-запрос с помощью cURL:
$ curl -X POST \
-H "Authorization: Bearer ${IAM_TOKEN}" \
-o speech.raw \
--data-urlencode "text=Привет, чувак! Назови-ка мне свои имя и фамилию?" \
-d "lang=ru-RU&folderId=${FOLDER_ID}&format=lpcm&sampleRateHertz=48000\
&emotion=good&voice=ermil" \
https://tts.api.cloud.yandex.net/speech/v1/tts:synthesizec
# в командной оболочке делайте все в одну строку, без “\”
Рассмотрим параметры запроса:
speech.raw – файл формата LPSM (несжатый звук). Это и есть озвученный текст в бинарном виде, который будет сохранен в текущую папку.
lang=ru-RU – язык текста.
emotion=good – эмоциональный окрас голоса. Пусть будет дружелюбным.
voice=ermil – текст будет озвучен мужским голосом Ermil. По умолчанию говорит Оксана.
https://tts.api.cloud.yandex.net/speech/v1/tts:synthesize – url, на который отправляется post-запрос на синтез речи дворецкого.
Бинарный файл послушать не получится, тогда установим утилиту SoX и сделаем конвертацию в wav:
$ brew install sox
$ sox -r 48000 -b 16 -e signed-integer -c 1 speech.raw speech.wav
speech.wav – приветствие готово и сохранено в текущую папку.
Для проигрывания wav внутри кода Python, можно взять, например, библиотеку simpleaudio. Она простая и не создает других потоков:
import simpleaudio as sa
def wave_play(trek):
wave_obj = sa.WaveObject.from_wave_file(trek)
play_obj = wave_obj.play()
play_obj.wait_done()
wave_play(speech.wav)
Итак, наш первый гость стоит перед входом на долгожданную party. Пытается открыть дверь, и вдруг слышит голос откуда-то сверху:
"Привет, чувак! Назови-ка мне свои имя и фамилию?" (или ваш вариант)
Отлично! Вы научили дворецкого приветствовать гостей, используя командную строку и cURL. А пока гость вспоминает ответ, научимся работать с API на языке Python.
Распознавание текста с помощью requests
Мы могли бы снова воспользоваться cURL для отправки ответа гостя на распознавание. Но мы пойдем дальше и напишем небольшую программу, основанную на подобных запросах.
Создайте готовый аудио-файл с ответом гостя. Сделать это можно через встроенный микрофон на вашем ноутбуке разными инструментами. Для macos подойдет Quick Time Player. Сконвертируйте аудио в формат ogg: name_guest.ogg. Можно онлайн, например, тут
Итак, пишем код на Python:
Для отправки запросов в Python воспользуемся стандартной библиотекой requests:
$ pip install requests
Импортируем в код:
import json
import requests
Зададим параметры, которые мы получили в командной строке:
URL = https://stt.api.cloud.yandex.net/speech/v1/stt:recognize
IAM_TOKEN = "CggaATEVAgA..."
ID_FOLDER = "b1gdt133kktmm89lr51l"
Аудио необходимо передавать в запрос в бинарном виде:
with open("name_guest.ogg", "rb") as f:
name_guest = f.read()
Давайте обернем весь процесс распознавания в функцию recognize:
def recognize(name_guest, IAM_TOKEN, ID_FOLDER):
""" Функция распознавания русской речи
:param IAM_TOKEN: (str)
:param outh_guest: ответ гостя (bytes)
:param ID_FOLDER: (str)
:return text: (str)
"""
# в поле заголовка передаем IAM_TOKEN:
headers = {'Authorization': f'Bearer {IAM_TOKEN}'}
# остальные параметры:
params = {
'lang': 'ru-RU',
'folderId': ID_FOLDER,
'sampleRateHertz': 48000,
}
response = requests.post(URL_REC, params=params, headers=headers, data=data_sound)
# бинарные ответ доступен через response.content, декодируем его:
decode_resp = response.content.decode('UTF-8')
# и загрузим в json, чтобы получить текст из аудио:
text = json.loads(decode_resp)
return text
Итак, чтобы дворецкий смог проверить гостя по списку, вызовем функцию и распознаем ответ:
name = recognize(name_guest, IAM_TOKEN, ID_FOLDER)
print(f"Гость утвержадет, что его зовут: {name}")
Теперь очередь за дворецким. В нашем случае, он вежлив ко всем. И прежде чем открыть или не открыть гостю дверь, он обратится лично. Например, так:
“Мы вам очень рады, <имя_и фамилия_гостя>, но вас нет в списке, сорян”
Для последующего синтеза вы можете снова воспользоваться CURL или так же написать функцию на Python. Принцип работы с API для синтеза и распознавания речи примерно одинаков.
Если вам позвонили из Yandex. Эти загадочные токены
Возможно, распознавать и синтезировать речь вам так понравится, что однажды вам позвонит милая девушка из Yandex и поинтересуется, все ли вам понятно в работе сервиса.
Продолжайте изучать документацию, и тогда вы узнаете, например, что iam_token живет не более 12 часов.
Чтобы быть вежливым, как наш дворецкий, и не перегружать сервера на Yandex, мы не будем генерировать iam_token чаще (при желании теперь стало можно генерить токен при каждом запросе). Заведите себе блокнотик и карандашик для записи даты генерации. Шутка.
Ведь у нас есть Python. Создадим функцию генерации. Снова используем requests:
import json
import requests
oauth_token = "AgAAAAAAHzS2AATuwTpDlcC9LExto-7iIHEWH9o"
def create_token(oauth_token):
params = {'yandexPassportOauthToken': oauth_token}
response = requests.post('https://iam.api.cloud.yandex.net/iam/v1/tokens', params=params)
decode_response = response.content.decode('UTF-8')
text = json.loads(decode_response)
iam_token = text.get('iamToken')
expires_iam_token = text.get('expiresAt')
return iam_token, xpires_iam_token
Вызовем функцию и положим результат в переменную:
result = create_token(oauth_token)
print("Токен успешно сгенерирован и действует до {}".format(result[1]))
Карандишик и блокнотик не пострадали, а у вас появилась полезная переменная xpires_iam_token.
Специально для вас по мотивам этого материала я написала маленький кусочек проекта виртуального дворецкого Butler. Звуковые эффекты входят в комплект :)
Автор: Екатерина Акилина