Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ Experimental support for TTS. Today the following providers are available:
* voicerss
* Microsoft Cognitive Services (Bing Text to Speech API)
* AWS Polly
* Google

It will use the one you configure in settings.json. If you define settings for multiple TTS services, it will not be guaranteed which one it will choose!

Expand Down Expand Up @@ -539,6 +540,70 @@ This is the current list of voice names and their corresponding language and acc
| Welsh | cy-GB | Female | Gwyneth |
| Welsh | English | en-GB-WLS | Male | Geraint |

#### Google

Does not require any API keys. Please note that Google has been known in the past to change the requirements for its Text-to-Speech API, and this may stop working in the future.

The following language codes are supported

| Language code | Language |
| ------------- | -------- |
| af | Afrikaans |
| sq | Albanian |
| ar | Arabic |
| hy | Armenian |
| bn | Bengali |
| ca | Catalan |
| zh | Chinese |
| zh-cn | Chinese (Mandarin/China) |
| zh-tw | Chinese (Mandarin/Taiwan) |
| zh-yue | Chinese (Cantonese) |
| hr | Croatian |
| cs | Czech |
| da | Danish |
| nl | Dutch |
| en | English |
| en-au | English (Australia) |
| en-gb | English (Great Britain) |
| en-us | English (United States) |
| eo | Esperanto |
| fi | Finnish |
| fr | Franch |
| de | German |
| el | Greek |
| hi | Hindi |
| hu | Hungarian |
| is | Icelandic |
| id | Indonesian |
| it | Italian |
| ja | Japanese |
| ko | Korean |
| la | Latin |
| lv | Latvian |
| mk | Macedonian |
| no | Norwegian |
| pl | Polish |
| pt | Portuguese |
| pt-br | Portuguese (Brazil) |
| ro | Romanian |
| ru | Russian |
| sr | Serbian |
| sk | Slovak |
| es | Spanish |
| es-es | Spanish (Spain) |
| es-us | Spanish (United States) |
| sw | Swahili |
| sv | Swedish |
| ta | Tamil |
| th | Thai |
| tr | Turkish |
| vi | Vietnamese |
| cy | Welsh |

Action is:

/[Room name]/say/[phrase][/[language_code]][/[announce volume]]
/sayall/[phrase][/[language_code]][/[announce volume]]

Line-in
-------
Expand Down
48 changes: 48 additions & 0 deletions lib/tts-providers/google.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'use strict';
const crypto = require('crypto');
const fs = require('fs');
const http = require('http');
const path = require('path');
const settings = require('../../settings');

function google(phrase, language) {
// Use Google tts translation service to create a mp3 file
const ttsRequestUrl = 'http://translate.google.com/translate_tts?client=tw-ob&tl=' + language + '&q=' + phrase;

// Construct a filesystem neutral filename
const phraseHash = crypto.createHash('sha1').update(phrase).digest('hex');
const filename = `google-${phraseHash}-${language}.mp3`;
const filepath = path.resolve(settings.webroot, 'tts', filename);

const expectedUri = `/tts/${filename}`;
try {
fs.accessSync(filepath, fs.R_OK);
return Promise.resolve(expectedUri);
} catch (err) {
console.log(`announce file for phrase "${phrase}" does not seem to exist, downloading`);
}

return new Promise((resolve, reject) => {
var file = fs.createWriteStream(filepath);
var options = {"headers": {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36"}, "host": "translate.google.com", "path": "/translate_tts?client=tw-ob&tl=" + language + "&q=" + encodeURIComponent(phrase) }
var callback = function (response) {
if (response.statusCode < 300 && response.statusCode >= 200) {
response.pipe(file);
file.on('finish', function () {
file.end();
resolve(expectedUri);
});
} else {
reject(new Error(`Download from google TTS failed with status ${response.statusCode}, ${response.message}`));

}
}

http.request(options, callback).on('error', function (err) {
fs.unlink(dest);
reject(err);
}).end();
});
}

module.exports = google;