mindsellers
72 subscribers
25 photos
8 files
32 links
Практики из жизни Linux-админа. Asterisk, Bash, Python и черная магия.

Сайт http://mindsellers.ru
Группа VK https://vk.com/mindsellers
ТыТруба https://www.youtube.com/channel/UC7LUJgzIUL4VGiOWctoa0fw
По всяким вопросам обращаться @alex_dmit
Download Telegram
Синтез и распознавание речи с помощью Yandex Speech API, python и asterisk
Сегодня рассмотрим довольно типовую задачу: информирование клиента в автоматическом режиме с синтезом речи, а также распознавание его ответа. Существует некоторое количество бесплатных инструментов как для синтеза, так и для распознавания речи, но к сожалению, ни один из них не может похвастаться высоким качеством работы. Именно поэтому рассмотрим использование платного сервиса от компании Yandex.

В первую очередь потребуется создать аккаунт на Облаке. Привязав любую пластиковую карту(с карты будет списана и тут же возвращена незначительная сумма) мы получим 4000 тестовых рублей аж на два месяца на использование любых облачных сервисов компании. Нас же интересуют исключительно речевые технологии. На момент написания статьи расценки таковы: синтез 1 млн символов - 183 рубля, распознавание фрагмента до 15 секунд - 15.2 копейки, что вполне доступно.

Яндекс предлагает довольно гибкое распределение ролей доступа к системе, но если мы используем только речевые технологии, то нам будет достаточно создать сервисный аккаунт и получить для него API-ключ, который мы будем в дальнейшем использовать в скриптах. Инструкция по данному вопросу доступна по ссылке.

Итак, рассмотрим типовой диалог:

Здравствуйте, Иван Иванович. Ваш заказ номер 234 456 доступен для получения в пункте выдачи по адресу Ленина, 1. Если вы хотите поговорить
с оператором, произнесите слово ОПЕРАТОР
Соединяем с оператором/всего доброго
Начнем со скрипта, который будет генерировать любой текст. На сайте Яндекса есть пример реализации на python, однако в примере рассматривается iam-аутентификация, а мы хотим работать по API-ключу, да и всякие свойства API описаны отдельно. Итак, листинг скрипта ниже, но для того, чтобы он работал, необходимо установить в системе sox, а также поставить requests и pysox через pip

pip install requests
pip install sox

#!/usr/bin/env python

import argparse
import requests
import sox
import os

def synthesize(output, text):
url = 'https://tts.api.cloud.yandex.net/speech/v1/tts:synthesize'
headers = {
'Authorization': 'Api-Key ' + 'AQVN33ioCUgKDF-XDXXXXXXXXX-oWqt7zIrX0ZW-', #авторизация
}

data = {
'text': text, #cинтезируемый текст
'lang': 'ru-RU', #язык
'voice': 'alyss', #голос
'emotion': 'good',
'format': 'lpcm', #формат
'sampleRateHertz': '8000'
}

resp=requests.post(url, headers=headers, data=data, stream=True, verify=False)
if resp.status_code != 200:
raise RuntimeError("Invalid response received: code: %d, message: %s" % (resp.status_code, resp.text))

for chunk in resp.iter_content(chunk_size=None):
with open(output, "wb") as f:
for content in chunk:
f.write(content)

tfm = sox.Transformer()
tfm.set_input_format(file_type='raw', rate=8000, bits=16, channels=1, encoding='signed-integer')
tfm.build(output, output+'.wav')
os.remove(output)


if name == "main":
parser = argparse.ArgumentParser()
parser.add_argument("--text", required=True, help="Text for synthesize")
parser.add_argument("--output", required=True, help="Output file name")
args = parser.parse_args()
synthesize(args.output, args.text)


Итак, мы принимаем 2 аргумента - текст и имя файла. Расширение мы указывать не будем, так как яндекс отдаст нам сырой файл, без заголовков, и далее, с помощью sox, нам все равно придется его превращать в кошерный wav. На выходе мы получим файл с расширением wav, который без проблем "сожрет" asterisk.

Теперь давайте рассмотрим скрипт, который будет заниматься распознаванием текста. В примере Яндекса он написан на python3, что нам, в общем, вполне подходит, так как результат его действий нам все равно нужно получить без перевода каретки(а то asterisk не сможет его обработать), а python2 по умолчанию так не умеет.

#!/usr/bin/env python3
import urllib.request
import json
import sys
import os

file=sys.argv[1]