1С + asterisk (потоковая передача данных из канала) часть 3. Реал тайм распознавание речи. Часть 1.

Публикация № 1300202

Администрирование - Торговое оборудование - Телефония, SIP

ami agi asterisk python web-socket flask extension-asterisk

Пример реализации потокового распознавания. Версия и релиз технологической платформы не имеет значения (так как 1Cа здесь нет, 1С есть в предыдущих статьях). Продолжение предыдущей статьи. (https://infostart.ru/1c/articles/1022878/).

Задача:

Построить реал тайм диалог с возможностью распознавания.

 

Общая логика решения задачи:

1. Дозвониться

2. Прочитать текст

3. Записать речь в поток

4. Выполнить распознавание речи

5. В зависимости от результата распознавания принять решение либо перейти в п2, либо в п6

6. В зависимости от принятия решения выполнить некие действия в 1С(бизнес логику)

7. Сохранить историю событий asterisk

8. Завершить звонок

 

Технологии:

1. 1С (выборка данных, инициализация вызова, обработка завершения, бизнес логика) 

2. asterisk(16) (ami сервер, agi клиент) (телефония)

3. python(3.6) (web сервер между фронтом и телефонией, ami клиент, agi сервер, web socket сервер)

4. Yandex.Cloud (распознавание речи)

5. С (extension asterisk, asterisk application, web socket клиент)

 

Общий принцип работы:

1) 1С регламентным заданием делает:

    1) Запрашивает у бэка статусы по ранее отправленным задачам

    2) Сохраняет статусы в регистре сведений

    3) Выборку по предварительно сформированным задачам. Из выборки берется телефон для набора, и определяется путь к файлу, который будет в дальнейшем воспроизводится. 1С делает гет запрос в бэк, передавая параметры (телефон, путь к файлу). (фактически создает таск в бэк)

    4) реализацию бизнес логики

2) Бэк:

    1) При старте:

        1) Запускает прослушку событий ами (ami)

        2) Стартует вэб сервер (flask)

        3) Стартует тисипи сервер(TCP) для обработки аги (agi)

        4) Стартует веб сокет сервер (web-socket) для обработки потока с астериска

    2) При получении события по ами делает запись в базу

    3) При получении события по аги делает логику диалога звонка(воспроизведение файлов, распознование с потока, управление фреймами от веб сокет сервера, запуск миксмонитор(запись звонка для прослушки), ложит трубку)

    4) При получении данных по веб сокету, хранит фреймы от астериска

    5) При получении запроса по HTTP парсит параметры, вызывает действие "Originate" с указанием  параметров(телефон, путь к файлу, контекст диалплана, канала вызывающей стороны)

3) Asterisk после успешного поднятия трубки на отвечающей стороне(через макрос):

    1) запускает тисипи поток(канала с передачей голоса) через расширение астериск(вызов application)

    2) "уходит" в аги

 

Отступление: 1Са в этой статье не будет, 1С был в предыдущих. С того времени мало что изменилось 

Часть 1. Исследование

Изначально были попытки реализации через просто буферное чтение файлов записи разговора в аги вида: RECORD FILE {FILENAME} {FORMAT} {ESCAPE_DIGITS} {TIMEOUT} {OFFSET_SAMPLES} {BEEP} {S(количество секунд тишины до завершения)} - это аги команда из мануала по астеру. Проблема заключается в том что аги это блокирующий контекст. То есть пока пишется файл записи разговора НЕЛЬЗЯ:

1. прервать запись(по нормальному имеется ввиду)(может только вызываемая сторона по дтфм)

2. запустить что то на выполнение в диалплане(аги)(запустив рекорд файл(запись), плейбэк(воспроизведение) запустится после завершения рекорд файл)

С этим жить можно было бы( и решить), НО люди могут начать говорить в момент воспроизведения файла\либо наоборот после окна записи(3\5 сек) что составляло задержки и не подходило совсем(в файле часть слов, либо вообще файл пустой)

Так же были попытки использования производных AGI(fast, E, Async), в результате чего было принято решение делать именно стрим(как и почему будет ниже), а не парсить файлы с записью по тайм ауту. Так как проблема оставалась либо блокировка в аги, либо не попадание в окно записи + задержки

Помимо аги комманды RECORD FILE(запись в файл), были попытки использовать аги комманды(application) CHAN SPY, EXTENDED CHAN SPY, APP JACK, AUDIO HOOK (сравнение, обзор эксплуатации и мысли по ним приводить здесь не буду, там еще на статью слов наберется), и прочее с сайта wiki.asterisk.org/wiki/display/AST/Asterisk+16+AGI+Commands, так же были игры с NGINX отдачей побуферно без особого успеха, либо мозгов не хватило, либо поняли что то не так, короче на завелось.

+\- в это же время попалось на глаза https://wiki.asterisk.org/wiki/display/AST/AudioSocket что привело к размышлениям об идеи собрать и использовать модуль https://wiki.asterisk.org/wiki/display/AST/Asterisk+18+Application_AudioSocket так как в у астериска 16 его конечно же не было ни в чистом виде(.с), ни в бинарном(.so)

(*ули нам, кабанам) Касательно AudioSocket, удалось его собрать https://github.com/CyCoreSystems/audiosocket, запустить, даже поток валить начал, + есть обертка для питона https://github.com/NormHarrison/audiosocket_server  но в нем был небольшой баг: в момент работы он грузил проц на 100 процентов, приложение стоящее внимание конечно.

Что было дальше?

Разбор https://github.com/CyCoreSystems/audiosocket/blob/master/asterisk/apps/app_audiosocket.c с целью понять как работает, откуда нагрузка проц, для того чтобы перепилить\напилить свою. Итог разбора был утешающим: 

ответ на первый вопрос если коротко в audiosocket_run блок ast_audiosocket_send_frame.

ответ на второй вопрос там же всё это обернуто в сишный while (1) {...} без прерываний по таймаутам.

Ну собственно всё ясно +\-:

1. интрефейс вызова модуля(load_module, unload_module, audiosocket_run, audiosocket_exec + хидеры) со стороны кор(core) астериска(api application)

2. как вообще снять стрим с астериска

3. что нужно делать дальше(разбить на потоки, так как приложение запускается в контексте аги и в процессе коры (core) астериска, что может сыграть злую шутку(тормоза в голосе, общие проблемы с астериском))

Следующим шагом был поход в вики раздел для разработчиков, а потом и гит хаб астера  поиск по ast_audiosocket_send_frame параллельно начали посещать идеи как разбить на потоки отправку, но до этого дело не дошло. В результате натыкаемся на ast_websocket_write https://asterisk-doxygen.osso.pub/master/api/db/db6/structast__websocket.html (int AST_OPTIONAL_API_NAME(ast_websocket_write)(struct ast_websocket *session, enum ast_websocket_opcode opcode, char *payload, uint64_t payload_size)). Немного погуглив внезапно находим https://github.com/nadirhamid/asterisk-audiofork смотрим в код, видим ast_pthread_create_detached_background(&thread, NULL, audiofork_thread, audiofork); треды, все дела, судя по коду то что нужно...

Ну в принципе ДА за исключением:

1. NOTE: you will need to use version 7.2.0 or below as there is currently a client side masking issue in res_http_websocket.c - здесь речь идет о не понятно с первого взгляда зачем использовать для ноды модуль сервера 7.2.0. если коротко не вникая в протокол веб сокетов могу сказать что он просто видоизменен, в том плане что в нем нет передачи бита маски со стороны клиента https://asterisk-doxygen.osso.pub/master/api/de/d4c/res__http__websocket_8c.html#a1a6e44db94d8b4e8c06bf456bb0174ad

2. не понятно как гуид в канал установить(я про переменную канала)(для того чтобы понимать какой поток какому звонку относится) в коде есть регистрация менеджера(ami), в мануале описан параметр, но так не получилось завести.

Решение 1 вопроса: пишем себ сокет сервер по реализацию клиента без учета маски https://github.com/dmarenin/asterisk-audiofork/blob/master/websocket_server.py, для сравнения полный протокол https://github.com/Pithikos/python-websocket-server/blob/master/websocket_server/websocket_server.py,

Решение 2 вопроса: добавляем отправку названия канала вида (SIP\xxx) первым сообщением https://github.com/dmarenin/asterisk-audiofork/commit/e1ca8142409e7ad11cdad501c7c5c5cbd68176c1

пример чтения фреймов с астера на веб сокет сервере https://github.com/dmarenin/asterisk-audiofork/blob/master/wss_sample.py

Собираем:

 

Запускаем:
  same => n,Verbose(audio fork was started continuing call)
  same => n,AudioFork(ws://192.168.555.222:8081/,D(out)i(WS_SOCKET_SESSION))

Проверяем:

Немного тестовых примеров:

https://yadi.sk/d/vAEREPOO4064cQ

https://yadi.sk/d/BZrdyE39Ln3Y4Q

https://yadi.sk/d/_L-0--p_7Z7Eqg

В следующей части будет рассмотрена техническая сторона вопроса

Специальные предложения

Оставьте свое сообщение

См. также

Настройка телефонии 1С:УНФ, Манго

Телефония, SIP Управление взаимоотношениями с клиентами (СRM) v8 УНФ УУ Бесплатно (free)

Настраиваем телефонию Манго в 1С:Управление нашей фирмой. Как это работает и с чем предстоит столкнуться.

25.11.2020    714    ogre2007    22    

Подключение АТС МТС к 1С:УНФ

Телефония, SIP v8 УНФ Россия Бесплатно (free)

В статье опишу реализацию HTTP сервиса для приема уведомлений от АТС.

28.06.2020    1698    malikov_pro    0    

Доработка подсистемы телефонии УНФ при использовании MANGO OFFICE

Телефония, SIP v8 УНФ Бесплатно (free)

В статье опишу исправление ошибок при создании вызова, получении записи разговора и маршрутизации входящих звонков.

29.04.2020    1900    malikov_pro    1    

1C + Телефония = /dev/hands + мозг (HowTo + FeedBack)

Телефония, SIP v8 1cv8.cf Россия Бесплатно (free)

FeedBack по интеграции 1С + Телефония. Что сработало. Что не понравилось.

15.01.2019    6247    rdbkzn    3    

Настройка Рарус: СофтФон с SIP телефонией на примере оператора Телфин

Управление взаимоотношениями с клиентами (СRM) Телефония, SIP Управление взаимоотношениями с клиентами (СRM) v8 1С:CRM Бесплатно (free)

Описание настройки Рарус СофтФон для работы с SIP телефонией на примере конфигурации Управление торговлей и взаимоотношениями с клиентами (CRM), редакция 2.0.

26.02.2018    18344    de0nis    0    

Как мы научили 1С генерировать IVR меню для Asterisk

Телефония, SIP Практика программирования v8 1cv8.cf Бесплатно (free)

Пример алгоритма интеллектуальной маршрутизации вызовов из 1С для Asterisk. На стороне 1С собирается статистика по касаниям между сотрудниками и клиентами, а на стороне Asterisk генерируется голосовое приветствие с помощью облачного сервиса синтеза речи.

15.12.2015    21713    jorikfon    7    

Что можно получить от интеграции 1С:CRM 8 и телефонии Asterisk

Телефония, SIP v8 Бесплатно (free)

Мы более года тесно занимаемся разработкой решений по интеграции телефонии на базе Asterisk и программ 1С. В первую очередь мы испытываем решения на себе, и я хочу поделиться опытом о том, что можно получить от такой интеграции. У нас используется терминальная схема работы с 1С:CRM. На столе у каждого сотрудника IP телефон, который подключен по локальной сети к IP ATС Askozia, развернутой вместе с терминальным 1С сервером внутри VMware инфраструктуры в ближайшем ЦОДе.

04.03.2013    38796    jorikfon    19    

Интеграция 1С:CRM и Asterisk с помощью PHP-AGI и веб-сервисов 1C

Управление взаимоотношениями с клиентами (СRM) Телефония, SIP Управление взаимоотношениями с клиентами (СRM) v8 1cv8.cf ИТ-компания Россия Бесплатно (free)

Давно зрел вопрос, можно ли встроить в диалплан Asterisk обращение к 1С:CRM системе для выполнения каких-либо управляющих действий и можно ли из 1С управлять IP АТС? Схема работы простейшая — при входящем звонке спросить у 1С что с ним делать, и если 1С ответила, то выполнить команду или продолжить стандартное выполнение маршрута вызова.

08.02.2013    32690    boffart    6    

ROM-Asterisk в высоконагруженных проектах интеграции

Телефония, SIP v7.7 v8 Бесплатно (free)

Хочу поделиться опытом, нажитым непосильным трудом при реализации больших проектов по интеграции 1С и Asterisk. ROM-Asterisk неплохо себя проявил под большими нагрузками. Выделю основные рекомендации, которые следует выполнять при интеграции с высоконагруженными Asterisk

13.01.2013    34238    oleg.rizvanov    22