Год назад для собственных нужд я написал обертку Yandex SpeechKit на Python, она получилась настолько простая и универсальная, что грех не поделиться : )
Кстати, вот она: Yandex SpeechKit Python SDK!
Для того, чтобы начать распознавать и синтезировать речь нам понадобится Python 3.6 или выше. Установить модуль можно из PyPI:
pip install speechkit
Прежде чем писать код, стоит сказать пару слов про то, как устроена платформа Yandex Cloud. Первым делом, Вам нужно зайти в консоль cloud.yandex.ru c помощью акаунта яндекса или создать такой. Затем, создать платежный аккаунт, активировав пробный период. В итоге получится что-то такое:
Стартовая страница консоли управленияПолучить идентификатор каталога можно из URL страницы каталога в консоли управления:
https://console.cloud.yandex.ru/folders/b1gd129pp9ha0vnvf5g7 , где b1gd129pp9ha0vnvf5g7 — это идентификатор каталога.
Он нам скоро понадобиться.
Для запроса к API SpeechKit нужно получить IAM-токен, Вам об этом беспокоиться не нужно, это уже «вшито» в библиотеку, нужно лишь передать исходные данные для создания сессии. Проще всего получить IAM-токен из OAuth-токена, Вашего аккаунта на яндексе, для этого перейдите по ссылке, нажмите Разрешить и скопируйте полученный OAuth-токен. В серьезных проектах лучше использовать авторизацию по JWT-токену или API-ключу для сервисного аккаунта.
Итак, у нас есть все, чтобы программа обрела голос, осталось лишь написать несколько строчек:
from speechkit import Session, SpeechSynthesis oauth_token = "AQAAAAAsHJkgAAhjwXshft5QgUuRkX0Wubhjlk" catalog_id = "b1gd129pp9ha0vnvf5g7" # Экземпляр класса `Session` можно получать из разных данных session = Session.from_yandex_passport_oauth_token(oauth_token, catalog_id) # Создаем экземляр класса `SpeechSynthesis`, передавая `session`, # который уже содержит нужный нам IAM-токен # и другие необходимые для API реквизиты для входа synthesizeAudio = SpeechSynthesis(session) # Метод `.synthesize()` позволяет синтезировать речь и сохранять ее в файл synthesizeAudio.synthesize( 'out.wav', text='Привет мир!', voice='oksana', format='lpcm', sampleRateHertz='16000' ) # `.synthesize_stream()` возвращает объект типа `io.BytesIO()` с аудиофайлом audio_data = synthesizeAudio.synthesize_stream( text='Привет мир, снова!', voice='oksana', format='lpcm', sampleRateHertz='16000' )
Вот так просто! Значение и полный список параметров можно посмотреть в документации яндекса или в документации библиотеки.
Теперь этот аудиофайл можно проиграть с помощью плеера или, например, с помощью библиотеки PyAudio. Кстати, в этом случае разумнее будет передавать объект с данными, а не сохранять их в файл, вот так:
import pyaudio
def pyaudio_play_audio_function(audio_data, num_channels=1,
sample_rate=16000, chunk_size=4000) -> None:
"""
Воспроизводит бинарный объект с аудио данными в формате lpcm (WAV)
:param bytes audio_data: данные сгенерированные спичкитом
:param integer num_channels: количество каналов, спичкит генерирует
моно дорожку, поэтому стоит оставить значение `1`
:param integer sample_rate: частота дискретизации, такая же
какую вы указали в параметре sampleRateHertz
:param integer chunk_size: размер семпла воспроизведения,
можно отрегулировать если появится потрескивание
"""
p = pyaudio.
PyAudio()
stream = p.open(
format=pyaudio.paInt16,
channels=num_channels,
rate=sample_rate,
output=True,
frames_per_buffer=chunk_size
)
try:
for i in range(0, len(audio_data), chunk_size):
stream.write(audio_data[i:i + chunk_size])
finally:
stream.stop_stream()
stream.close()
p.terminate()
sample_rate = 16000 # частота дискретизации должна
# совпадать при синтезе и воспроизведении
audio_data = synthesizeAudio.synthesize_stream(
text='Привет мир, снова и снова!',
voice='oksana', format='lpcm', sampleRateHertz=sample_rate
)
# Воспроизводим синтезированный файл
pyaudio_play_audio_function(audio_data, sample_rate=sample_rate)Теперь мы можем проговорить голосом яндекса что-нибудь прямо из программы, осталось научиться распознавать команды и можно прикручивать голосовое управление к чайнику, кофеварке, утюгу и пылесосу!
Яндекс предоставляет три способа распознавания: потоковое распознавание, синхронное распознавание и асинхронное распознавание.
О том чем они отличаются и зачем нужны можно почитать на официальной страничке.
Если вкратце, потоковое распознавание нужно для того, чтобы получать текст прямо во время записи и стриминга аудио, и обрабатывать результаты на лету. Например, умная колонка может начать задумываться как ей ответить, в то время, как пользователь еще не закончил фразу. Пример использования потокового распознавания в гитхабе библиотеки, еще подробнее можно почитать в документации.
Асинхронное распознавание нужно для перевода в текстовый формат очень длинных аудиозаписей, оно дешевле остальных методов, но для получения результата придется немного подождать. Вот пример использования и описание класса.
Мы же будем использовать самый простой способ — синхронное распознавание. Для этого запишем сообщение в файл и сохраним в формате WAV.
from speechkit import ShortAudioRecognition
# Читаем файл
with open('voice.wav', 'rb') as f:
data = f.
read()
# Создаем экземпляр класса с помощью `session` полученного ранее
recognizeShortAudio = ShortAudioRecognition(session)
# Передаем файл и его формат в метод `.recognize()`,
# который возвращает строку с текстом
text = recognizeShortAudio.recognize(
data, format='lpcm', sampleRateHertz='48000')
print(text)Ура! Теперь можно прикрутить голосовые команды к чему угодно. Вот ссылка на полное описание метода, если Вы хотите передавать файл в формате, отличном от WAV, например.
Напоследок покажу, как с помощью PyAudio записать голос, который можно будет потом передать в спичкит для распознавания:
import io
import wave
import pyaudio
def record_audio(seconds, sample_rate,
chunk_size=4000, num_channels=1) -> bytes:
"""
Записывает аудио данной продолжительности и возвращает бинарный объект с данными
:param integer seconds: Время записи в секундах
:param integer sample_rate: частота дискретизации, такая же
какую вы указали в параметре sampleRateHertz
:param integer chunk_size: размер семпла записи
:param integer num_channels: количество каналов, в режимер синхронного
распознавания спичкит принимает моно дорожку,
поэтому стоит оставить значение `1`
:return: Возвращает объект BytesIO с аудио данными в формате WAV
:rtype: bytes
"""
p = pyaudio.
PyAudio()
stream = p.open(
format=pyaudio.paInt16,
channels=num_channels,
rate=sample_rate,
input=True,
frames_per_buffer=chunk_size
)
frames = []
try:
for i in range(0, int(sample_rate / chunk_size * seconds)):
data = stream.read(chunk_size)
frames.append(data)
finally:
stream.stop_stream()
stream.close()
p.terminate()
container = io.BytesIO()
wf = wave.open(container, 'wb')
wf.setnchannels(num_channels)
wf.setsampwidth(p.get_sample_size(pyaudio.paInt16))
wf.setframerate(sample_rate)
wf.writeframes(b''.join(frames))
container.seek(0)
return container
sample_rate = 16000 # частота дискретизации должна
# совпадать при записи и распознавании
# Записываем аудио продолжительностью 3 секунды
data = record_audio(3, sample_rate)
# Отправляем на распознавание
text = recognizeShortAudio.recognize(
data, format='lpcm', sampleRateHertz=sample_rate)
print(text)На этом все.
Надеюсь, вам пригодилась библиотека : ) Буду рад пул-реквестам!
Спасибо за внимание!
Речевые технологии Yandex SpeechKit для оценки качества оказания услуг технической поддержки
Для начала пару слов о сервис Yandex SpeechKit.
Это инструмент который позволяет использовать речевые технологии Яндекса: распознавание речи (Speech-to-Text) и синтез речи (Text-to-Speech), имеет различные возможности потоковому распознавания речи. Ну и самое главное — мы применяли решение в облаке.
Основанная задача проекта — автоматизировать процесс получения подтверждение пользователем, что его заявка выполнена специалистом технической поддержки в полном объеме.
В качестве системы работы с заявками у заказчика используется HPSM, где храниться вся информация о заявителе, его обращениях и все данные о выполнении заявок.
АТС – Asterisk. В качестве технологии распознавания и синтеза речи Yandex SpeechKit.
Был реализован следующий алгоритм:
Решение получало данные об закрытых инцидентах и с использованием технологий Yandex SpeechKit получает голосовую запись с формулировкой задачи.
Далее через АТС дозванивается до заявителя и попросила его подтвердить что все работы выполнены.
Полученный ответ оправляется Yandex SpeechKit для перевода его в текст. Результат записывается в систему.
Решение получилось достаточно интересным. В процессе у робота даже появилось имя Митя.
Когда поступает звонок с подтверждением наше решение представляется «Здравствуйте, я робот Митя …»
Хотели бы с вами поделиться итогами работы за первые 2 недели:
Всего робот совершил 2 201 звонков из них ему удалось дозвониться и записать ответ 480 раз.
Работа Мити за этот период сберегла заказчику почти 11 часов. Из них 8 — это время, которые могли потратить их специалисты без результата(точнее, не дозвонились бы до заявителя).
|
Наименование |
Среднее время которое тратит сотрудник контакт центар |
Результат |
Итого за день |
|
ч. |
Робота, шт. |
ч. мин. сек. | |
|
Попытка дозвониться |
0:00:16 |
1721 |
7:38:56 |
|
Дозвонился и пользователь подтвердил выполнение |
0:00:19 |
404 |
2:07:56 |
|
Дозвонился и пользователь не подтвердил выполнение или не сразу вспомнил что за заявка |
|
76 |
0:57:00 |
|
ИТОГО |
|
2201 |
10:43:52 |
За первый месяц было реализовано много изменений, которые смогли сделать этот сервис более удобным для нашего заказчика и его пользователей.
Из них успели реализовать:
Для оценки эффективности работы был проведен опрос среди пользователей, список вопросов ниже который помог определить дальнейшие задачи для автоматизации.
Как вы бы хотели подтверждать выполнение заявки:
Что В работе Робота вам не нравится или бы хотелось улучшить:
Хотелось бы отметить, что главным результатом применения Yandex SpeechKit стало сэкономленное время специалистов.
Context, токен, строка папки) (*SDK, ошибка)Просмотр исходного кода
const STTAPIEndpoint = "stt.api.cloud.yandex.net:443"
STTAPIEndpoint используется для всех запросов на распознавание голоса.
Этот раздел пуст.
Этот раздел пуст.
тип RecognitionClient struct {
// содержит отфильтрованные или неэкспортированные поля
} RecognitionClient обертывает SttService_StreamingRecognizeClient
func (rc *RecognitionClient) Ошибка Close()
Close закрывает gRPC-соединение RecognitionClient
func (rc *RecognitionClient) Ошибка CloseSend()
CloseSend обертывает SttService_StreamingRecognizeClient.
CloseSend
func (rc *RecognitionClient) NewAudioRequest(audioFilePath string) (*stt.StreamingRecognitionRequest, ошибка)
NewAudioRequest возвращает правильно установленный StreamingRecognitionRequest для аудиофайла
func (rc *RecognitionClient) NewConfigRequest(строка языка) *stt.StreamingRecognitionRequest
NewConfigRequest возвращает правильно установленный StreamingRecognitionRequest для конфигурации
func (rc *RecognitionClient) Recv() (*stt.StreamingRecognitionResponse, ошибка)
Recv обертывает SttService_StreamingRecognizeClient.Recv
func (rc *RecognitionClient) RecvAll() ([]*stt.StreamingRecognitionResponse, ошибка)
RecvAll накапливает все ответы от RecognitionClient
func (rc *RecognitionClient) Отправить (req *stt.StreamingRecognitionRequest) ошибка
Отправка оборачивает SttService_StreamingRecognizeClient.Send
func (rc *RecognitionClient) SimpleRecognize(filePath, lang string) (string, error)
SimpleRecognize отправляет аудиофайл на распознавание через Yandex SpeechKit с параметрами по умолчанию
введите структуру SDK {
// содержит отфильтрованные или неэкспортированные поля
} SDK описывает метод Yandex Cloud SDK, необходимый для распознавания голоса
func NewSDK(ctx context.Context, token, folder string) (*SDK, ошибка)
NewSDK создает новый экземпляр SDK
func (sdk *SDK) Ошибка Close()
Close закрывает подключение SDK
func (sdk *SDK) IAMToken(ctx context.Context) (строка, ошибка)
IAMToken запрашивает новый токен IAM для запросов API
func (sdk *SDK) NewRecognitionClient(ctx context.Context) (*RecognitionClient, ошибка)
NewRecognitionClient создает новый RecognitionClient
Python SDK для Yandex SpeechKit API. Этот SDK позволяет использовать облачный API для распознавания и синтеза речи от Яндекс.
Для получения дополнительной информации посетите документацию Yandex Speechkit API Docs. Эта библиотека поддерживает распознавание коротких и длинных звуков с помощью комплекта речи
Предполагая, что у вас установлены Python и virtualenv , настройте свою среду и установите необходимые зависимости
например, или вы можете установить библиотеку, используя pip :
$ git clone https://github.
com/TikhonP/yandex-speechkit-lib-python.git
$ cd yandex-speechkit-lib-python
$ virtualenv venv
...
$ . venv/bin/активировать
$ python -m pip install -r требования.txt
$ python -m pip установить.
python -m pip установить набор речи
Дополнительные сведения см. в документации по набору речи Информация. Документы в формате PDF
Есть поддержка распознавания длинного и короткого аудио и синтеза. Для получения дополнительной информации, пожалуйста, прочитайте документы ниже.
Сначала нужно создать сессию для авторизации:
из спичкита импортировать сессию
oauth_token = str('')
ID_папки = str('<идентификатор_папки>')
api_key = str('')
jwt_token = str('')
oauth_session = Session.from_yandex_passport_oauth_token(oauth_token, folder_id)
api_key_session = Session.from_api_key(api_key, x_client_request_id_header=True, x_data_logging_enabled=True)
# Вы можете использовать параметры `x_client_request_id_header` и `x_data_logging_enabled` для устранения неполадок с распознаванием yandex
# Используйте метод `Session.
get_x_client_request_id()`, чтобы получить значение x_client_request_id.
jwt_session = Session.from_jwt(jwt_token)
Использовать созданный сеанс для выполнения других запросов.
Также есть функции для получения учетных данных (дополнительную информацию см. в документации): Speechkit.auth.generate_jwt , speechkit.auth.get_iam_token , speechkit.auth.get_api_key
Короткое аудио:
Rekit Shortudio importationA распознатьShortAudio = ShortAudioRecognition(сеанс) с open(str(‘/Users/tikhon/Desktop/out.wav’), str(‘rb’)) как f: данные = f.read() print (recognizeShortAudio.recognize (данные, формат = ‘lpcm’, sampleRateHertz = ‘48000’)) # Будет напечатано: ‘текст, который нужно распознать’Посмотрите пример с длинным аудио long_audio_recognition.py .
Посмотрите пример с потоковой передачей audio streaming_recognize.py
из импорта набора речи SpeechSynthesis
синтезаудио = синтез речи (сеанс)
синтезаудио.