FreePBX | Register | Issues | Wiki | Portal | Support

TTS Engine Custom - Amazon Polly - 24 languages

(Jerson Jr) #63

Look this example:

exten => s,1,Progress()
same => n,Set(audio=${SHELL(node /opt/aws-nodejs-sample/script.js --mp3=/home/asterisk/audio-${cpf}.mp3 --text=’${nome}’ --wav=/var/lib/asterisk/sounds/audio-${cpf})})
same => n,Playback(audio-${cpf})


Vote here :slight_smile:


I exactly followed theclevercrib’s “working summary” above and was able to get the script to generate .mp3 and .wav files when I call inbound and trigger a TTS event. They are generated properly and sound fine when I play them manually. Problem is there is no sound on the incoming phone line. When I use flite and call inbound there is sound.

Any ideas what I might be missing?

I’m running FreePBX Sangoma distribution. Asterisk 13.

(Jerson Jr) #66

Change “ext” => “sln” to “ext” => “wav”

(Adam V.) #67

Thanks to everyone on this post. I have learned a lot! I have come up with a different approach and not reliant on the modules Text to Speech engine or Text to Speech application. Using the dialplan + PHP

You still need an Amazon account. And node.js

Kudos to @jersonjunior!
Sample project to demonstrate usage of the AWS SDK for Node.js:

cd /opt/
git clone
cd aws-nodejs-sample
npm install
npm install optimist
npm install child_process

nano script.js

#!/usr/bin/env node
// Load the SDK
var argv = require('optimist').argv;
const AWS = require('aws-sdk')
const Fs = require('fs')
var child_process = require('child_process');
// Create an Polly client
const Polly = new AWS.Polly({
accessKeyId: "youraccessKeyIdgoeshere",
secretAccessKey: "yoursecretAccessKeygoeshere",
signatureVersion: 'v4',
region: 'us-east-1'


letparams = {
'Text': argv.text,
'OutputFormat': 'mp3',
'SampleRate': '8000',
'VoiceId': 'Joanna'

Polly.synthesizeSpeech(params, (err, data) => {
if (err) {
} else if (data) {
if (data.AudioStream instanceof Buffer) {
Fs.writeFile(argv.mp3, data.AudioStream, function(err) {
if (err) {
return console.log(err)
console.log("The file was saved!")
var output = child_process.execSync('lame --decode ' + argv.mp3 + ' ' + '-b 8000' + ' ' + argv.wav + '.wav');

Press ctrl+x y enter to save and exit

nano /var/lib/asterisk/agi-bin/pollysimple.php

#!/usr/bin/php -q
// [polly-simple]
$agi = new AGI();

$text= "Hello, this is a test of Amazon Polly. Change this text to hear something different.";

$id= uniqid();
shell_exec("node /opt/aws-nodejs-sample/script.js --mp3=/tmp/polly-$id.mp3 --text='$text' --wav=/tmp/polly-$id");

$mp3file = "/tmp/polly-$id.mp3";
unlink($mp3file) or die("Couldn't delete file"); //deletes mp3 file

$wavfile = "/tmp/polly-$id.wav";
unlink($wavfile) or die("Couldn't delete file"); //deletes wav file

Press ctrl+x y enter to save and exit

Now we have to change permissions:
cd /var/lib/asterisk/agi-bin/
chown asterisk:asterisk pollysimple.php
chmod +x pollysimple.php

Now to put it all together:
Freepbx gui: Admin -> Config Edit -> extensions_custom.conf:

;internal extension of [polly-simple]
exten => 400,1,Goto(polly-simple,s,1)

;can be referenced by creating a Custom Destination
;Target= polly-simple,s,1
;Description= A simple Amazon Polly test
exten => s,1,Answer()
exten => s,n,AGI(/var/lib/asterisk/agi-bin/pollysimple.php)
exten => s,n,Hangup()
Click Save and Apply

Calling extension 400 will play the text in pollysimple.php if everything went ok.
The temp files are deleted.
Creating a Custom Destination is optional. Unless you want to use it in another application.

Good luck! Let me know if you come across any issues.