artem
15.03.2018
1695

Распознавание речи в Asterisk

Сначала определим план действий для такой функции:

 

1. Определиться с сервисом, который будет распознавать речь. (Для этого использовался wit.ai).

2. Производить запись речи клиента и помещать во временное хранилище.

3. Отослать запись на выбранный сервис и получить результат обработки.

4. Сравнить с текущими фамилиями сотрудников.

5. Совершить вызов на сотрудника, если таковой нашелся.

 

Все описанные действия в статье на сервере телефонии необходимо выполнять от имени суперпользователя (root). Установка и настройка производилась на предустановленной системе CentOS 6.9 + Asterisk 11.25.1 + FreePBX 13. 

Сервис распознавания речи

Про сервис Wit.ai было рассказано тут. Так же в той статье описано получение API ключа, для дальнейшей работы.

Запись речи клиента.

Как известно в астериске есть стандартное приложение для записи голоса. Record. Для начала надо предупредить клиента о произнесении нужной информации. Для этого используем приложение Playback.

exten=>s,1,Set(QW=${CALLERID(num)})
        same => n,Playback(custom/second_name)
        same => n,Record(/tmp/${CDR(uniqueid)}.wav,,5)

second_name – имя файла записи, которое будет воспроизводиться для клиента.

/tmp/${CDR(uniqueid)}.wav — файл куда будет записываться сообщение клиента

5 — Таймаут записи в секундах. (Для произнесения добавочного или фамилии будет достаточно 5 секунд)

Wait – даем немного времени для освобождения файла от записи.

Обработка записи

Для побработки записи будем использовать скрипт. (Будет использоваться php.)

 

#!/usr/bin/php -q
<?php
require (‘phpagi.php’);
        $agi = new AGI();
$recname = strval($agi->request[‘uniqueid’]);
$url = ‘https://api.wit.ai/speech?v=20160526&access_token=API_wit_ai’;
 
$data = file_get_contents(‘/tmp/’.$recname.’.wav’);
 
$headers = array();
$headers[] = ‘X-Requested-With: JSONHttpRequest’;
$headers[] = ‘Content-Type: audio/wav’;
$resource = curl_init();
 
curl_setopt($resource, CURLOPT_URL, $url);
curl_setopt($resource, CURLOPT_HTTPHEADER,$headers);
curl_setopt($resource, CURLOPT_POST,1);
curl_setopt($resource, CURLOPT_BINARYTRANSFER, true);
curl_setopt($resource, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($resource, CURLOPT_POSTFIELDS,$data);
 
$result= curl_exec($resource);
$result= json_decode($result);
 
curl_close($resource);
 
$result = serialize($result);
 
preg_match_all(‘/[а-я А-Я]+/u’,$result,$matches);

Подключаем библиотеку phpagi. Она нужна для передачи параметра uniqueid в скрипт. Т.к. Мы сохраняем файл голоса клиента с именем UNIQUEID звонка. (см. выше).

recname – имя нашей записи.

url – урл к сервису распознавания речи

API_wit_ai — АПИ ключ, который мы ранее получили в ЛК wit.ai.

Далее методами CURL отправляем содержимое файла $data к сервису wit. На что, через некоторое время получаем JSON ответ, с содержанием в поле _text нашей распознанной речи:

{s:5:”_text”;s:12:”Зайцев”;s:8:”entities”;O:8:”stdClass”:0{}s:6:”msg_id”;s:17:”0I2OngrCjdKXb3cHA”;}

Сравнение с текущими фамилиями

Распознавание речи не всегда бывает точным. Бывают случаи, когда человек кортавит или же шипилявит, поэтому точно распознать речь не получится. И не всегда присылаемый текст совпадает с нашими ожиданиями, поэтому был применен алгоритм Левенштейна.

 

// введенное слово с опечаткой
$input = $matches[0][0];
// массив сверяемых слов
$words  = array(‘Зайцев’ => 105,’Иванов’ => 201,’Петров’ => 220,’Сидоров’ => 216,
                ‘Грачев’ => 217);
                                //Массив вызываемых абонентов
// кратчайшее расстояние пока еще не найдено
$shortest = -1;
// проходим по словам для нахождения самого близкого варианта
foreach ($words as $word => $ext) {
    // вычисляем расстояние между входным словом и текущим
    $lev = levenshtein($input, $word);
    // проверяем полное совпадение
    if ($lev == 0) {
        // это ближайшее слово (точное совпадение)
        $closest = $word;
        $shortest = 0;
        // выходим из цикла – мы нашли точное совпадение
        break;
    }
    // если это расстояние меньше следующего наименьшего расстояния
    // ИЛИ если следующее самое короткое слово еще не было найдено
    if ($lev <= $shortest || $shortest < 0) {
        // устанивливаем ближайшее совпадение и кратчайшее расстояние
        $closest  = $word;
        $shortest = $lev;
    }
}

Далее нам надо передать в диалплан необходимый номер телефона (указан в словаре $words)

 

$agi->set_variable(“VOICE_NUM”,$words[$closest]);
$agi->set_variable(“VOICE_NAME”,$closest);
?>

 

VOICE_NUM – номер клиента

VOICE_NAME – Фамилия клиента (для дебага в консоле)

Совершить вызов на сотрудника

        same => n,AGI(voice.php)
        same => n,Goto(ext-local,${VOICE_NUM},1)

AGI(voice.php) – вызов нашего скрипта для дальнейшей передачи переменных в диалплан

Goto — переходим в необходимый контекст для вызова распознанного номера (в FreePBX по умолчанию это ext-local).

 
avatar
  Подписаться  
Уведомление о

Остались вопросы?

Я - Першин Артём, менеджер компании Voxlink. Хотите уточнить детали или готовы оставить заявку? Укажите номер телефона, я перезвоню в течение 3-х секунд.

VoIP оборудование

ближайшие курсы

ближайшие Вебинары

ONLINE

Why Choose HUGE?

Unlimited pre-designed elements

Each and every design element is designed for retina ready display on all kind of devices

User friendly interface and design

Each and every design element is designed for retina ready display on all kind of devices

100% editable layered PSD files

Each and every design element is designed for retina ready display on all kind of devices

Created using shape layers

Each and every design element is designed for retina ready display on all kind of devices