Pull to refresh

Распознавание речи во FreePBX с помощью Яндекс Speechkit

Reading time 5 min
Views 19K
Привет, хабр!

Решил поделиться опытом интеграции Asterisk и сервиса Яндекса по распознаванию речи.

Загорелось моему заказчику внедрить в свою АТС фичу Voice2Text.

В качестве АТС использовался FreePBX.

Сразу в голову пришло использование сервисов распознавания речи от Google, но после нескольких часов безуспешных попыток добиться нужного результата решил попробовоть аналогичный сервис Яндекса.

Подробности под катом.


Исходные данные:

FreePBX Distro 12 Stable-6.12.65, CentOS 6.5, Asterisk 11 + неимоверное желание реализовать фичу Voice2Text :)

По умолчанию FreePBX пишет все записи в .wav, нам же нужно передать файлы на распознавание в .mp3. Для это воспользуемся sendmailmp3.

Работу sendmailmp3 можно разбить на некоторые этапы:
  • «поймать» поток
  • проанализировать содержание электронной почты
  • разделить сообщение на части
  • извлечь аудиофайл
  • конвертировать wav в mp3
  • восстановить содержимое почты
  • Передать сообщение команде sendmail


Воспользуемся скриптом, который установит sendmailmp3 и все необходимые для работы пакеты.

Переходим в /tmp:
cd /tmp


Cкачиваем скрипт, который установит sendmailmp3:

wget http://pbxinaflash.com/installmp3stt.sh


Делаем файл исполняемым:
chmod +x installmp3stt.sh


И запускаем скрипт:
./installmp3stt.sh


Далее идем в веб-интерфейс FreePBX, Вкладка Settings, Voicemail Admin, Settings:

И там в поле mailcmd пишем /usr/sbin/sendmailmp3
А в поле format: wav
image

Теперь наши сообщения будут пересылаться на почту в формате mp3, добавим фичу Voice2Text.

Выбор сервисов Яндекса обусловлен тем, что можно отсылать файл прямо в mp3, а не перекодировать во flac или speex (по крайней мере другой информации о поддерживаемых форматах я не нашел), а также тем, что максимальная длина сообщения значительно больше нежели у гугла.

Прежде чем наш скрипт начнет полноценно работать, необходимо пройти по ссылке, далее зайти в кабинет разработчика, авторизироваться в нем с помощью почтового ящика яндекса и запросить API-ключ. После этого вам придет письмо на указанную почту с дальнейшими инструкциями:
image

После того, как ваш ключ активирован, необходимо сформировать curl-запрос, который будет отсылать наш файлик на распознавание. Вид должен быть следующий:
asr.yandex.net/asr_xml?
uuid=<уникальный идентификатор пользователя>
& key=<API-ключ>
& topic=<тема голосового запроса>
& [lang=<язык запроса>]

Поддерживаются следующие форматы:
  • audio/x-speex 1
  • audio/x-pcm;bit=16;rate=8000
  • audio/x-pcm;bit=16;rate=16000 2
  • audio/x-alaw;bit=13;rate=8000
  • audio/x-wav
  • audio/x-mpeg-3 3


Ответ возвращается в виде XML, содержащего n-best список гипотез распознавания (до 5 значений) с указанием степени достоверности для каждой гипотезы.
Пример удачного распознавания:
<?xml version=«1.0» encoding=«utf-8»?>
улица басманная

Пример неудачного распознавания:
<?xml version=«1.0» encoding=«utf-8»?>
/>

В результате чего на указанный вами почтовый ящик падает сообщение с вариантами распознавания и аттачем с mp3-файлом подобное этому:

image

Получившийся в результате скрипт имеет следующий вид:
sendmailmp3
#! /bin/sh 
# Asterisk voicemail attachment conversion script, including voice recognition using Google API
#
# Revision history :
# 22/11/2010 - V1.0 - Creation by N. Bernaerts
# 07/02/2012 - V1.1 - Add handling of mails without attachment (thanks to Paul Thompson)
# 01/05/2012 - V1.2 - Use mktemp, pushd & popd
# 08/05/2012 - V1.3 - Change mp3 compression to CBR to solve some smartphone compatibility (thanks to Luca Mancino)
# 01/08/2012 - V1.4 - Add PATH definition to avoid any problem (thanks to Christopher Wolff)
# 31/01/2013 - V2.0 - Add Google Voice Recognition feature (thanks to Daniel Dainty idea and sponsoring :-)
# 04/02/2013 - V2.1 - Handle error in case of voicemail too long to be converted

# set language for voice recognition (en-US, en-GB, fr-FR, ...)
LANGUAGE="ru_RU"

# set PATH
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

# save the current directory 
pushd .
 
# create a temporary directory and cd to it 
TMPDIR=$(mktemp -d)
cd $TMPDIR 
 
# dump the stream to a temporary file 
cat >> stream.org 
 
# get the boundary 
BOUNDARY=`grep "boundary=" stream.org | cut -d'"' -f 2` 
 
# cut the file into parts 
# stream.part - header before the boundary 
# stream.part1 - header after the bounday 
# stream.part2 - body of the message 
# stream.part3 - attachment in base64 (WAV file) 
# stream.part4 - footer of the message 
awk '/'$BOUNDARY'/{i++}{print > "stream.part"i}' stream.org 
 
# if mail is having no audio attachment (plain text) 
PLAINTEXT=`cat stream.part1 | grep 'plain'` 
if [ "$PLAINTEXT" != "" ] 
then 
 
  # prepare to send the original stream 
  cat stream.org > stream.new 
 
# else, if mail is having audio attachment 
else 
 
  # cut the attachment into parts 
  # stream.part3.head - header of attachment 
  # stream.part3.wav.base64 - wav file of attachment (encoded base64) 
  sed '7,$d' stream.part3 > stream.part3.wav.head 
  sed '1,6d' stream.part3 > stream.part3.wav.base64 
 
  # convert the base64 file to a wav file 
  dos2unix -o stream.part3.wav.base64 
  base64 -di stream.part3.wav.base64 > stream.part3.wav 
 
  # convert wav file to mp3 file
  # -b 24 is using CBR, giving better compatibility on smartphones (you can use -b 32 to increase quality)
  # -V 2 is using VBR, a good compromise between quality and size for voice audio files
  lame -m m -b 24 stream.part3.wav stream.part3.mp3
 
  # convert back mp3 to base64 file 
  base64 stream.part3.mp3 > stream.part3.mp3.base64 
 
  # generate the new mp3 attachment header 
  # change Type: audio/x-wav to Type: audio/mpeg 
  # change name="msg----.wav" to name="msg----.mp3" 
  sed 's/x-wav/mpeg/g' stream.part3.wav.head | sed 's/.wav/.mp3/g' > stream.part3.mp3.head 
 
  # convert wav file to flac compatible for Google speech recognition
#  sox stream.part3.wav -r 16000 -b 16 -c 1 audio.flac vad reverse vad reverse lowpass -2 2500

  # call Google Voice Recognition sending flac file as POST
   curl -v -4 "asr.yandex.net/asr_xml?key=23988820-8719-4a2e-82ba-9ddd5a9bfe67&uuid=12345678123456781234567812345678&topic=queries&lang=ru-RU" -H "Content-Type: audio/x-mpeg-3" --data-binary "@stream.part3.mp3" 1>audio.txt
#  curl --data-binary @audio.flac --header 'Content-type: audio/x-flac; rate=16000' 'https://www.google.com/speech-api/v2/recognize?key=AIzaSyB5lwncPRYpNrHXtN-Sy-LNDMLLU5vM1n8&xjerr=1&client=chromium&pfilter=0&lang='ru_RU'&maxresults=1' 1>audio.txt
  
 
# extract the transcript and confidence results
  FILETOOBIG=`cat audio.txt | grep "<HTML>"`
  TRANSCRIPT=`cat audio.txt | cut -d"," -f3 | sed 's/^.*utterance\":\"\(.*\)\"$/\1/g'`
  CONFIDENCE=`cat audio.txt | cut -d"," -f4 | sed 's/^.*confidence\":0.\([0-9][0-9]\).*$/\1/g'`

  # generate first part of mail body, converting it to LF only
  mv stream.part stream.new
  cat stream.part1 >> stream.new
  sed '$d' < stream.part2 >> stream.new

  # beginning of transcription section
  echo "---" >> stream.new

  # if audio attachment is too big
  if [ "$FILETOOBIG" != "" ]
  then
    # error message
    echo "Voice message is too long to be transcripted." >> stream.new
  else
    # append result of transcription
    echo "Message seems to be ( $CONFIDENCE% confidence ) :" >> stream.new
    echo "$TRANSCRIPT" >> stream.new
  fi

  # end of message body
  tail -1 stream.part2 >> stream.new

  # append mp3 header
  cat stream.part3.mp3.head >> stream.new
  dos2unix -o stream.new

  # append base64 mp3 to mail body, keeping CRLF 
  unix2dos -o stream.part3.mp3.base64 
  cat stream.part3.mp3.base64 >> stream.new 
 
  # append end of mail body, converting it to LF only 
  echo "" >> stream.tmp 
  echo "" >> stream.tmp 
  cat stream.part4 >> stream.tmp 
  dos2unix -o stream.tmp 
  cat stream.tmp >> stream.new 
 
fi 
 
# send the mail thru sendmail 
cat stream.new | sendmail -t 
 
# go back to original directory 
popd
 
# remove all temporary files and temporary directory 
sleep 50
rm -Rf $TMPDIR




На мой взгляд этот вариант несколько проще, нежели было описано тут, т.к. все сводится к запуску и изменению одного скрипта и пары кликов в веб-интерфейсе, а также присылает записи в mp3, а не в .wav. Безусловно, кто-то скажет, что это не unix-way:), но может кому-то будет полезно, хотя бы в целях ознакомления.
Tags:
Hubs:
+16
Comments 13
Comments Comments 13

Articles