Skip to content

Instantly share code, notes, and snippets.

@ipoddubny
Created May 22, 2016 17:41
Show Gist options
  • Save ipoddubny/f7142ec62ea497ecac306f6fd2029c28 to your computer and use it in GitHub Desktop.
Save ipoddubny/f7142ec62ea497ecac306f6fd2029c28 to your computer and use it in GitHub Desktop.
Yandex text-to-speech FastAGI server for Asterisk
/*
* System requirements:
* - lame
* - sox
*
* Usage:
* exten => ...,AGI(agi://localhost:3000/?text=${URIENCODE(Hello, world)})
*/
'use strict';
const AgiServer = require('ding-dong');
const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));
const tts = Promise.promisify(require('yandex-speech').TTS);
const querystring = require('querystring');
const crypto = require('crypto');
const spawn = require('child_process').spawn;
function handler (context) {
Promise.resolve(context.onEvent('variables'))
.bind({})
.then(function (vars) {
const qs = vars.agi_network_script.split('?')[1];
this.params = querystring.parse(qs);
const sha1 = crypto.createHash('sha1').update(this.params.text).digest('hex');
this.fileName = `/tmp/tts-${sha1}`;
this.fileNameWav = this.fileName + '.wav';
this.fileNameMp3 = this.fileName + '.mp3';
return fs.accessAsync(this.fileNameWav);
})
.catch(function () {
const opts = {
text: this.params.text,
file: this.fileNameMp3
};
return tts(opts)
.then(() => {
return new Promise((resolve, reject) => {
let cmd = spawn('/bin/sh', ['-c', `lame --decode ${this.fileNameMp3} - | sox -v 0.5 -t wav - -t wav -b 16 -r 8000 -c 1 ${this.fileNameWav}`]);
cmd.on('close', resolve);
});
});
})
.then(function () {
return context.streamFile(this.fileName);
})
.then(function () {
return context.end();
});
}
var agi = new AgiServer(handler);
agi.start(3000);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment