Распознавание речи в Asterisk с использованием Yandex SpeechKit HTTP API



Статья написана по мотивам Синтез и распознавание речи от Google для Asterisk, с не большими изменениями. Для распознавания речи используется платформа Yandex SpeechKit HTTP API.

В диалплане все без изменений (пример для extensions.ael, по моему AEL белее удобен чем extensions.conf):

s => {
        Answer();
        Wait(1);
        Record(/tmp/${UNIQUEID}.wav,3,20);
        AGI(yandex_voice.php,/tmp/${UNIQUEID});
        NoOp(${TEXT});
        Hangup();
};


Пример очень примитивен: отвечаем на звонок, ждем 1с., записываем речь, распознаем сказанное, выводим в консоль Asterisk-а распознанный текст, но принцип работы понятен.

Теперь что касается непосредственно самого скрипта.

Для начала немного об используемых переменных:

$key = 'my_secret_key' — это ваш ключ от API, получить его можно написав письмо на speechkit@yandex-team.ru;

$topic = 'maps' — тема для распознавания, возможны следующие варианты:

• freeform — произвольный текст, заметки и т.д. Вариант применения: переводим в текст сообщение голосовой почты и отправляем его на email или виде SMS.
• general — web поисковые запросы, не могу придумать к чему это можно применить в данном контексте;
• maps — адреса, GEO-точки (название баров, автозаправочные станции, гостиницы и так далее), и т.д.;
• music — названия песен, музыкальных групп и т.д.

$lang = 'ru-RU' — язык на котором будет происходить распознавание, на данный момент поддерживается русский 'ru-RU' и турецкий 'tr-TR', причем турецкий поддерживается только для тем «general» и «maps»;

$uuid = '12345678123456781234567812345678' — 32-x цифирная строка, должна быть уникальна для каждого запроса.

Более детально API описано в файле Yandex_SpeechKit_HTTP_API_May[5].pdf который будет отправлен вам вместе с ключом, хотя более короткого мануала по API читать не доводилось, но это и к лучшему.

В моем варианте настройки Asterisk-а файл скрипта находятся в папке: /usr/share/asterisk/agi-bin/

И собственно сам код yandex_voice.php:

#!/usr/bin/php -q
<?
$agivars = array();
while (!feof(STDIN)) {
    $agivar = trim(fgets(STDIN));
    if ($agivar === '')
        break;

    $agivar = explode(':', $agivar);
    $agivars[$agivar[0]] = trim($agivar[1]);
}
extract($agivars);

$filename = $_SERVER["argv"][1];
$key = 'my_secret_key';
$topic = "maps";
$lang = "ru-RU";
$uuid = "12345678123456781234567812345678";

system('sox '.$filename.'.wav -r 16000 -b 16 -c 1 '.$filename.'-pcm.wav');
$cmd = exec('curl --silent -F "Content-Type=audio/x-pcm;bit=16;rate=16000" -F "audio=@'.$filename.'-pcm.wav" asr.yandex.net/asr_xml\?key='.$key.'\&uuid='.$uuid .'\&topic='.$topic.'\&lang='.$lang, $xml); 

$res_xml = implode($xml);
if (preg_match('!<variant .*?>(.*)</variant>!si', $res_xml, $arr)) $voice_text = $arr[1];
	else $voice_text='';
	
echo 'SET VARIABLE TEXT "'.$voice_text.'"'."\n";
fgets(STDIN);
echo 'VERBOSE ("'.$voice_text.'")'."\n";
fgets(STDIN);
exit(0);
?>


Да, код не идеален, его можно и нужно улучшить. Как вариант сделать более универсальным передавая ему большую часть переменных аргументами или использовать его как функцию в другом AGI или ARI скрипте. Как он сейчас у меня и используется, для распознания города в котором находится абонент.
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 15

    0
    А генератор речи от Yandex-а случайно не знаете как попользовать?
      0
      Ксожелению пока не знаю, есть ли он вообще, сам задаюсь этим вопросом
        +1
        В переводчике от Yandex-а он присутствует. И качество генерации, IMHO, лучше чем у Google.
          0
          К сожалению, проговаривает только 1 строчку текста, если больше, то контрол озвучивания становится недоступным, правда из Yandex браузера не проверял, может там все хорошо.
        +3
        похоже достаточно банально:

        mplayer 'http://tts.voicetech.yandex.net/tts?format=mp3&quality=hi&platform=web&application=translate&lang=ru_RU&text=Привет мир'

        хз, после скольки попыток они банить будут
          0
          Ого. То что нужно. Спасибо.
            0
            Повелительное наклонение кривовато, гугл лучше читает.
              0
              Дааа, что-то с ударениями и расстановкой пауз у движка Яндекса проблемы. Офлайновый RHVoice гораздо лучше синтезирует речь.
                0
                Спасибо!
              0
              Даешь голосовую антикапчу!
                –1
                Скрипт у Вас странный. Смесь sh и PHP.
                  0
                  Никто же не мешает представить свой вариант.
                  0
                  Интересно что получили в результате? На сколько точно распознается речь?
                    0
                    Спасибо автору за информацию. Попросил ключ и немного потестил. Дикторскую начитку распознает на 100% (IVR меню). А вот обычную речь распознает примерно так:
                    квартира предприятия от дома к 10 минута для тебя сено
                    Кто угадает, о чем был разговор может взять с полки пирожок. :)
                    Но в любом случае это большой шаг вперед. Я надеюсь, что ребята из яндекса, со временем, допилят сервис и всем будет хорошо.

                    P.S. Распознавал все в режиме freeform.
                    P.P.S. Сервис не хавает файлы размером больше ~1 mb выдавая Content-size limit reached!
                      0
                      Может кому пригодится под мак слушает тишину записывает конвертирует отправляет:

                      устанавливаем пакет SOX из macports или brew

                      rec test.flac silence 1 1 3% 1 0.9 3% && sox test.flac -r 16000 -b 16 -c 1 test-pcm.wav && curl "https://asr.yandex.net/asr_xml?key=YOUR API KEY IS HERE&uuid=12345678123456781234567812345678&topic=freeform&lang=ru_RU" -F "Content-Type=audio/x-pcm;bit=16;rate=16000" -F "audio=@test-pcm.wav"

                      Only users with full accounts can post comments. Log in, please.