614 профессионалов IT в этом Telegram чате. “ы с нами?

ћаксим (BioDamage)

ƒрузь€, сегодн€ речь пойдет о синтезе речи в Asterisk. Ётот простой способ позволит вам озвучивать требуемое голосовое сообщение в структурах IVR или обычных приветстви€х. ƒа где угодно. ѕрофит этого решени€:

  1. ≈диный голос дл€ всех аудио Ц файлов;
  2.  эширование и сохранение озвученных текстов, фраз в виде медиа - файлов, дл€ последующего использовани€ на Asterisk;

ѕолучаем токен

ѕриступим. ѕрежде всего нужно получить API - токен на использование сервиса от яндекс. Ётот процесс расписан в статье по ссылке ниже (раздел ѕолучение API - токена Yandex.SpeechKit):

¬озвращайтесь с токеном и будем приступать к коду :)


 одим!

ƒл€ начала создадим директорию /var/lib/asterisk/tts/ и дадим права. “ам мы будем хранить текстовый файл, благодар€ которому, сможем идентифицировать аудио Ц файлы по совпадению MD5 названи€. ¬нутри файла будет фраза:

mkdir /var/lib/asterisk/tts/
chown asterisk:asterisk /var/lib/asterisk/tts/
chmod 775 /var/lib/asterisk/tts/

¬ зависимости от дистрибутива и вариантов установки IP Ц ј“— Asterisk, звуковые файлы могут располагатьс€ в другой директории. ¬ы можете самосто€тельно поправить это в скрипте.

»спользовать будем AGI приложение. “радиционно, комментарии к коду прикладываютс€:

#!/usr/bin/php -q
<?php
error_reporting(0); // выключаем ошибки, необ€зательно, нужно в процесcе дебага скрипта

require('phpagi.php'); 
$agi = new AGI();
$str = $agi->request['agi_arg_1']; //записываем в переменную текст, который необходимо озвучить
$str = iconv('cp1251', 'utf-8', $str); // конвертируем в кириллическую кодировку
$md5 = md5($str); //вычисл€ем md5 - хэш от переменной $str
$prefix = '/var/lib/asterisk/sounds/ru/custom/'; //устанавливаем директорию дл€ файлов. ћы ее создавали по ходу движени€
$filename = $prefix.$md5; //устанавливаем название файла(оно будет равно md5 текста)
$format = 'wav'; //устанавливаем формат получаемого файла от яндекс
$quality = 'hi'; //устанавливаем качество

$speaker = 'oksana'; //выбираем голос. Ќа момент написани€ статьи доступны женские голоса: jane, oksana, alyss и omazh и мужские голоса: zahar и ermil.
$emotion = 'evil'; // выбираем интонацию голоса, good Ч радостный, доброжелательный, evil Ч раздраженный, neutral Ч нейтральный (используетс€ по умолчанию). Ѕудем злее :)
$speed = '0.9'; // данный параметр отвечает за скорость (темп) речи, подбираетс€ опытным путем на слух, в данном случае оптимальный
$key = '¬аш_токен'; //ваш токен, который вы получили ранее.

if (!file_exists($filename.'.wav')) {

$qs = http_build_query(array("format" => $format,"quality" => $quality,"lang" => "ru-RU","speaker" => $speaker,"speed" => $speed,"key" => $key,"emotion" => $emotion, "text" => $str)); //формируем строку запроса
$ctx = stream_context_create(array("http"=>array("method"=>"GET","header"=>"Referer: \r\n")));
$soundfile = file_get_contents("https://tts.voicetech.yandex.net/generate?".$qs, false, $ctx); //запрашиваем файл
$file = fopen("file1.wav", "w"); //открываем файл дл€ записи 
fwrite($file, $soundfile); // пишем в файл данные
fclose($file); //закрываем файл
shell_exec('sox -t raw -r 48k -e signed-integer -b 16 -c 1 file1.wav -t wav -r 8k -c 1 '.$filename.'.wav'); //конвертируем файл под требовани€ Asterisk и закидываем в директорию дл€ аудио
shell_exec('chown asterisk:asterisk '.$filename.'.wav');
shell_exec('chmod 775 '.$filename.'.wav'); // даем файлу нужные пермишны;
shell_exec('rm -f file1.wav'); // удал€ем  файл, который создали в процессе обращени€ к API; 
shell_exec('echo '.$str.' > /var/lib/asterisk/tts/'.$md5.'.txt'); // добавл€ем магии ;-) о ней ниже в тексте статьи.
}
$agi->exec('Playback',"custom/$md5"); //проигрываем файл звон€щему.
?>
—качать скрипт синтеза речи
ѕосле загрузки файла, сохраните его с расширением .php

—охран€ем скрипт как texttospeech.php и закидываем его в директорию /var/lib/asterisk/agi-bin. ѕосле, даем последовательность следующих команд:

dos2unix /var/lib/asterisk/agi-bin/texttospeech.php 
chown asterisk:asterisk /var/lib/asterisk/agi-bin/texttospeech.php 
chmod 775 /var/lib/asterisk/agi-bin/texttospeech.php

 ак вы могли заметить, скрипт настраиваетс€. √олос, интонаци€, скорость речи, качество получаемого файла Ц подлежат корректировке дл€ вашей задачи.

—хема работы всего процесса следующа€:

  1. —крипт получает из диалплана текст по AGI и сохран€ет в переменной;
  2. ≈сли у нас уже существует аудио Ц файл дл€ заранее записанной фразы, мы отдаем в диалплан команду на воспроизведение. ≈сли нет Ц обращаемс€ к API;
  3. —крипт отправл€ет запрос в сторону API яндекса;
  4. ѕроисходит конвертаци€ полученного аудио Ц файла в нужный формат;
  5. ƒаем права файлу дл€ воспроизведени€ на Asterisk и удал€ем временный файл;
  6. ƒелаем отметку о создании файла в служебный текстовый файл;
  7. ¬оспроизводим файл;

ј как заставить скрипт работать?

ќчень просто. ќткрываем файл /etc/asterisk/extensions_custom.conf дл€ редактировани€ и добавл€ем в него следующую запись:

[text_to_speech]
exten => s,1,Answer()
exten => s,2,AGI(texttospeech.php,"ѕривет! Ёто ћерион Ќетворкс. ≈сли ты слышишь это сообщение, значит все сделал правильно!")

—охран€ем изменени€ и прыгаем в FreePBX. Ѕудем вызывать кастомный контекста из FreePBX. ƒл€ этого воспользуемс€ модулем Custom Destinations. ѕереходим по пути AdminCustom Destinations и нажимаем Add Destination:

Custom Destination FreePBX дл€ синтеза речи

Ќастроили и сохранили. Ќаша задумка такова Ц человек звонит на наш номер, набирает 13 и попадает на синтезированное сообщение. ѕереходим в главный IVR и в секции IVR Entries добавл€ем следующее:

—интез речи из диаплана Asterisk

«воним, провер€ем. –аботает :) ≈сли хотите заменить фразу, которую нужно озвучить, просто поправьте ее в файле /etc/asterisk/extensions_custom.conf.


ѕолезна ли ¬ам эта стать€?