node-red-contrib-tts-ultimate 1.0.32 → 1.0.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/README.md +20 -10
- package/package.json +4 -3
- package/ttsultimate/ttsultimate-config.html +25 -4
- package/ttsultimate/ttsultimate-config.js +100 -7
- package/ttsultimate/ttsultimate.js +35 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.paypal.me/techtoday)
|
|
4
4
|
|
|
5
|
+
<p>
|
|
6
|
+
<b>Version 1.0.33</b> October 2021<br/>
|
|
7
|
+
- NEW VOICE ENGINE: Microsoft Azure TTS.<br/>
|
|
8
|
+
<p>
|
|
5
9
|
<p>
|
|
6
10
|
<b>Version 1.0.32</b> September 2021<br/>
|
|
7
11
|
- Fix few restore issues. Line-in restore fix and only when it was playing. Amazon Music and Spotify considered as stream instead of music queue.<br/>
|
package/README.md
CHANGED
|
@@ -22,10 +22,11 @@
|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
## DESCRIPTION
|
|
25
|
-
This node transforms a text into a speech audio. You can hear the voice through Sonos.<br/>
|
|
26
|
-
Uses Amazon Polly
|
|
25
|
+
This node transforms a text into a speech audio. You can generate an audio file, or hear the voice through Sonos, bluetooth speakers, web pages, etc.<br/>
|
|
26
|
+
Uses Amazon Polly, Google TTS voices (even without credentials nor registration) and Microsoft TTS Azure voices, and you can use it with **your own audio file** as well and it can be used **totally offline** even without the use of TTS, without internet connection.<br/>
|
|
27
|
+
The node can also create a ***TTS file (without the use of any Sonos device)***, to be read by third parties nodes.<br/>
|
|
27
28
|
This is a major ***upgrade from the previously popular node SonosPollyTTS*** (SonosPollyTTS is not developed anymore).<br/>
|
|
28
|
-
**Node v.
|
|
29
|
+
**Node v.12.0.0 or newer is needed**.
|
|
29
30
|
|
|
30
31
|
[](https://www.paypal.me/techtoday)
|
|
31
32
|
|
|
@@ -33,7 +34,8 @@ This is a major ***upgrade from the previously popular node SonosPollyTTS*** (So
|
|
|
33
34
|
* See <a href="https://github.com/Supergiovane/node-red-contrib-tts-ultimate/blob/master/CHANGELOG.md">here the changelog</a>
|
|
34
35
|
|
|
35
36
|
## FEATURES
|
|
36
|
-
* **
|
|
37
|
+
* **Output audio file**: the node can just create the TTS file to be used by other nodes. In this case, you doesn't need to use Sonos as player.
|
|
38
|
+
* **Amazon Voices, Gooogle Translate Voices, Google TTS Voices and Microsoft TTS Azure voices** are all supported, with all avaiables languages and genders.
|
|
37
39
|
* **Automatic grouping** is supported. You can group all players you want to play your announcements.
|
|
38
40
|
* **Automatic discovery** of your players.
|
|
39
41
|
* **Automatic resume of music** queue (including radio stations, but here, some users reports problem resuming ***radio stations*** and, because of lack of Sonos API documentation, the issue cannot currently be fixed), at exact track, at exact time.
|
|
@@ -69,16 +71,11 @@ PORT USED BY THE NODE ARE 1980 (DEFAULT) AND 1400 (FOR SONOS DISCOVER). <br/>
|
|
|
69
71
|
PLEASE ALLOW MDNS AND UDP AS WELL
|
|
70
72
|
|
|
71
73
|
**TTS Service**<br/>
|
|
72
|
-
You can choose between Google (without credentials), Amazon AWS (Polly)
|
|
74
|
+
You can choose between Google (without credentials), Amazon AWS (Polly), Google TTS (require credentials and registration to google) or Microsoft Azure TTS engines.<br/>
|
|
73
75
|
For Google TTS Engine, you can choose pitch and speed rate of the voice.
|
|
74
76
|
<br/>
|
|
75
77
|
<br/>
|
|
76
78
|
|
|
77
|
-
* **TTS Service using Google (without credentials)**<br/>
|
|
78
|
-
This is the simplest way. Just select the voice and you're done. You don't need any credential and you don't even need to be registered to any google service. The voice list is more limited than other services, but it works without hassles.
|
|
79
|
-
|
|
80
|
-
<br/>
|
|
81
|
-
|
|
82
79
|
* **TTS Service using Amazon AWS (Polly)**<br/>
|
|
83
80
|
> HOW-TO in Deutsch: for german users, there is a very helpful how-to, where you can learn how to use the node and how to register to Amazon AWS Polly as well: here: https://technikkram.net/blog/2020/09/26/sonos-sprachausgabe-mit-raspberry-pi-node-red-und-amazon-polly-fuer-homematic-oder-knx-systeme
|
|
84
81
|
|
|
@@ -89,6 +86,11 @@ For Google TTS Engine, you can choose pitch and speed rate of the voice.
|
|
|
89
86
|
AWS access Secret key.
|
|
90
87
|
<br/>
|
|
91
88
|
|
|
89
|
+
* **TTS Service using Google (without credentials)**<br/>
|
|
90
|
+
This is the simplest way. Just select the voice and you're done. You don't need any credential and you don't even need to be registered to any google service. The voice list is more limited than other services, but it works without hassles.
|
|
91
|
+
|
|
92
|
+
<br/>
|
|
93
|
+
|
|
92
94
|
* **TTS Service using Google TTS**<br/>
|
|
93
95
|
For Google TTS Engine, you can choose pitch and speed rate of the voice.<br/>
|
|
94
96
|
**Google credentials file path**<br/>
|
|
@@ -100,6 +102,14 @@ For Google TTS Engine, you can choose pitch and speed rate of the voice.
|
|
|
100
102
|
|
|
101
103
|
<br/>
|
|
102
104
|
|
|
105
|
+
* **TTS Service using Microsot Azure TTS**<br/>
|
|
106
|
+
For Microsoft Azure TTS Engine, you need to have a microsoft account and register to the Azure portal.<br/>
|
|
107
|
+
After your registration here https://portal.azure.com, you need to create a Voice Service, then click to Keys and Endpoint and copy/paste the KEY and your Location (for example westus).<br/>
|
|
108
|
+
Then paste both into the TTS-Ultimate engine configuration window and restart node-red.
|
|
109
|
+
|
|
110
|
+
<br/>
|
|
111
|
+
|
|
112
|
+
|
|
103
113
|
**Node-Red IP**<br/>
|
|
104
114
|
set IP of your node-red machine. Sonos will connect to this address in order to play TTS. You can also write any value you want, for example 127.0.0.1 in this field (**don't leave this field blank in any case**), if you don't want to use Sonos as player. Please see below, the section **TTS-ULTIMATE NODE**, property **Player**.
|
|
105
115
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-red-contrib-tts-ultimate",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Transforms the text in speech and hear it using Sonos player. Works with voices from Amazon, Google (without credentials as well) or your own voice. Update of the popular SonosPollyTTS node.",
|
|
3
|
+
"version": "1.0.33",
|
|
4
|
+
"description": "Transforms the text in speech and hear it using Sonos player or generate an audio file to be used with third parties nodes. Works with voices from Amazon, Google (without credentials as well), Microsoft TTS Azure, or your own voice. You can also only create a TTS file to be read by third party nodes. Update of the popular SonosPollyTTS node.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "test"
|
|
@@ -46,7 +46,8 @@
|
|
|
46
46
|
"os": ">=0.1.1",
|
|
47
47
|
"path": ">=0.12.7",
|
|
48
48
|
"@google-cloud/text-to-speech": "3.3.1",
|
|
49
|
-
"google-translate-tts": ">=0.2.1"
|
|
49
|
+
"google-translate-tts": ">=0.2.1",
|
|
50
|
+
"microsoft-cognitiveservices-speech-sdk": ">=1.18.1"
|
|
50
51
|
},
|
|
51
52
|
"devDependencies": {
|
|
52
53
|
"eslint": ">=4.18.2",
|
|
@@ -22,7 +22,9 @@
|
|
|
22
22
|
},
|
|
23
23
|
credentials: {
|
|
24
24
|
accessKey: { type: "text" },
|
|
25
|
-
secretKey: { type: "password" }
|
|
25
|
+
secretKey: { type: "password" },
|
|
26
|
+
mssubscriptionKey: { type: "text" },
|
|
27
|
+
mslocation: { type: "text" }
|
|
26
28
|
},
|
|
27
29
|
label: function () {
|
|
28
30
|
return this.name || "";
|
|
@@ -58,14 +60,21 @@
|
|
|
58
60
|
// ##########################################################
|
|
59
61
|
$("#node-config-input-ttsservice").change(function (e) {
|
|
60
62
|
if ($("#node-config-input-ttsservice").val() == "polly") {
|
|
61
|
-
$("#pollyForm").show();
|
|
62
63
|
$("#GoogleForm").hide();
|
|
64
|
+
$("#microsoftAzureForm").hide();
|
|
65
|
+
$("#pollyForm").show();
|
|
63
66
|
} else if ($("#node-config-input-ttsservice").val() == "googletts") {
|
|
67
|
+
$("#microsoftAzureForm").hide();
|
|
64
68
|
$("#pollyForm").hide();
|
|
65
69
|
$("#GoogleForm").show();
|
|
66
|
-
}else{
|
|
70
|
+
} else if ($("#node-config-input-ttsservice").val() == "googletranslate") {
|
|
67
71
|
$("#pollyForm").hide();
|
|
68
72
|
$("#GoogleForm").hide();
|
|
73
|
+
$("#microsoftAzureForm").hide();
|
|
74
|
+
} else if ($("#node-config-input-ttsservice").val() == "microsoftazuretts") {
|
|
75
|
+
$("#pollyForm").hide();
|
|
76
|
+
$("#GoogleForm").hide();
|
|
77
|
+
$("#microsoftAzureForm").show();
|
|
69
78
|
}
|
|
70
79
|
});
|
|
71
80
|
// ##########################################################
|
|
@@ -161,7 +170,8 @@
|
|
|
161
170
|
<select id="node-config-input-ttsservice">
|
|
162
171
|
<option value="polly">Amazon Polly</option>
|
|
163
172
|
<option value="googletts">Google TTS</option>
|
|
164
|
-
<option value="googletranslate">Google without authentication</option>
|
|
173
|
+
<option value="googletranslate">Google without authentication</option>
|
|
174
|
+
<option value="microsoftazuretts">Microsoft Azure TTS</option>
|
|
165
175
|
</select>  <b><span style="color:red"><i class="fa fa-question-circle"></i> <a target="_blank" href="https://github.com/Supergiovane/node-red-contrib-tts-ultimate"><u>Help configure</u></a></span>
|
|
166
176
|
</div>
|
|
167
177
|
<div id="pollyForm">
|
|
@@ -180,6 +190,17 @@
|
|
|
180
190
|
<input style="width:180px" id="googleCredentialsPath" type="file">
|
|
181
191
|
</div>
|
|
182
192
|
</div>
|
|
193
|
+
<div id="microsoftAzureForm">
|
|
194
|
+
<div class="form-row">
|
|
195
|
+
<label style="width:180px" for="node-config-input-mssubscriptionKey"><i class="fa fa-user"></i> Azure subscription key</label>
|
|
196
|
+
<input style="width:200px" type="text" id="node-config-input-mssubscriptionKey">
|
|
197
|
+
</div>
|
|
198
|
+
<div class="form-row">
|
|
199
|
+
<label style="width:180px" for="node-config-input-mslocation"><i class="fa fa-user"></i> Azure location (ex:westeurope)</label>
|
|
200
|
+
<input style="width:200px" type="text" id="node-config-input-mslocation">
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
|
|
183
204
|
<div class="form-row">
|
|
184
205
|
<label for="node-config-input-purgediratrestart"><i class="fa fa-folder-o"></i> TTS Cache</label>
|
|
185
206
|
<select id="node-config-input-purgediratrestart">
|
|
@@ -4,6 +4,7 @@ module.exports = function (RED) {
|
|
|
4
4
|
const AWS = require('aws-sdk');
|
|
5
5
|
const GoogleTTS = require('@google-cloud/text-to-speech');
|
|
6
6
|
const GoogleTranslate = require('google-translate-tts'); // TTS without credentials, limited to 200 chars per row.
|
|
7
|
+
const microsoftAzureTTS = require("microsoft-cognitiveservices-speech-sdk"); // 12/10/2021
|
|
7
8
|
var fs = require('fs');
|
|
8
9
|
var path = require("path");
|
|
9
10
|
var formidable = require('formidable');
|
|
@@ -21,7 +22,7 @@ module.exports = function (RED) {
|
|
|
21
22
|
node.noderedipaddress = typeof config.noderedipaddress === "undefined" ? "" : config.noderedipaddress;
|
|
22
23
|
node.userDir = path.join(RED.settings.userDir, "sonospollyttsstorage"); // 09/03/2020 Storage of ttsultimate (otherwise, at each upgrade to a newer version, the node path is wiped out and recreated, loosing all custom files)
|
|
23
24
|
node.whoIsUsingTheServer = ""; // Client node.id using the server, because only a ttsultimate node can use the serve at once.
|
|
24
|
-
node.ttsservice = config.ttsservice || "
|
|
25
|
+
node.ttsservice = config.ttsservice || "googletranslate";
|
|
25
26
|
|
|
26
27
|
// 03/06/2019 you can select the temp dir
|
|
27
28
|
//#region "SETUP PATHS"
|
|
@@ -76,26 +77,114 @@ module.exports = function (RED) {
|
|
|
76
77
|
//#endregion
|
|
77
78
|
|
|
78
79
|
|
|
79
|
-
// 23/12/2020 Set environment path of googleTTS
|
|
80
80
|
//#region "INSTANTIATE SERVICE ENGINES"
|
|
81
|
+
// POLLY
|
|
81
82
|
var params = {
|
|
82
83
|
accessKeyId: node.credentials.accessKey,
|
|
83
84
|
secretAccessKey: node.credentials.secretKey,
|
|
84
85
|
apiVersion: '2016-06-10'
|
|
85
86
|
};
|
|
86
|
-
|
|
87
|
+
try {
|
|
88
|
+
node.polly = new AWS.Polly(params);
|
|
89
|
+
RED.log.info("ttsultimate.config: Polly service enabled.")
|
|
90
|
+
} catch (error) {
|
|
91
|
+
RED.log.warn("ttsultimate.config: Polly service disabled. " + error.message)
|
|
92
|
+
}
|
|
87
93
|
|
|
94
|
+
// Google TTS with authentication
|
|
88
95
|
if (node.ttsservice === "googletts") {
|
|
89
96
|
try {
|
|
90
|
-
// Set
|
|
97
|
+
// 23/12/2020 Set environment path of googleTTS
|
|
91
98
|
RED.log.info("ttsultimate-config: Google credentials are stored in the file " + path.join(node.userDir, "ttsultimategooglecredentials", "googlecredentials.json"));
|
|
92
99
|
process.env.GOOGLE_APPLICATION_CREDENTIALS = path.join(node.userDir, "ttsultimategooglecredentials", "googlecredentials.json");
|
|
93
100
|
} catch (error) {
|
|
101
|
+
RED.log.warn("ttsultimate.config: Google Translate free service error: " + error.message)
|
|
94
102
|
}
|
|
95
103
|
|
|
96
104
|
}
|
|
97
|
-
|
|
98
|
-
|
|
105
|
+
try {
|
|
106
|
+
node.googleTTS = new GoogleTTS.TextToSpeechClient();
|
|
107
|
+
RED.log.info("ttsultimate.config: Google Translate free service enabled. ")
|
|
108
|
+
} catch (error) {
|
|
109
|
+
RED.log.warn("ttsultimate.config: Google Translate free service disabled. " + error.message)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
// Google Translate without authentication
|
|
114
|
+
try {
|
|
115
|
+
node.googleTranslateTTS = GoogleTranslate;
|
|
116
|
+
} catch (error) {
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
// 12/10/2021 Microsoft Azure TTS SpeechConfig.fromSubscription(subscriptionKey, serviceRegion)
|
|
121
|
+
// #########################################
|
|
122
|
+
node.setMicrosoftAzureVoice = function (_voiceName) {
|
|
123
|
+
console.log ("ILSIGNOREBUONO",_voiceName)
|
|
124
|
+
let speechConfig = microsoftAzureTTS.SpeechConfig.fromSubscription(node.credentials.mssubscriptionKey, node.credentials.mslocation);
|
|
125
|
+
speechConfig.speechSynthesisVoiceName = _voiceName;
|
|
126
|
+
speechConfig.speechSynthesisOutputFormat = microsoftAzureTTS.SpeechSynthesisOutputFormat.Audio16Khz32KBitRateMonoMp3;
|
|
127
|
+
node.microsoftAzureTTS = new microsoftAzureTTS.SpeechSynthesizer(speechConfig);
|
|
128
|
+
return node.microsoftAzureTTS;
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
let speechConfig = microsoftAzureTTS.SpeechConfig.fromSubscription(node.credentials.mssubscriptionKey, node.credentials.mslocation);
|
|
132
|
+
speechConfig.speechSynthesisLanguage = "it-IT";
|
|
133
|
+
speechConfig.speechSynthesisVoiceName = "it-IT-IsabellaNeural";
|
|
134
|
+
speechConfig.speechSynthesisOutputFormat = microsoftAzureTTS.SpeechSynthesisOutputFormat.Audio16Khz32KBitRateMonoMp3;
|
|
135
|
+
node.microsoftAzureTTS = new microsoftAzureTTS.SpeechSynthesizer(speechConfig);
|
|
136
|
+
node.microsoftAzureTTSVoiceList = [];
|
|
137
|
+
if (node.ttsservice === "microsoftazuretts") {
|
|
138
|
+
// Get the voices
|
|
139
|
+
async function listVoicesAzure() {
|
|
140
|
+
const httpsAzure = require('https')
|
|
141
|
+
let options = {
|
|
142
|
+
hostname: node.credentials.mslocation + '.tts.speech.microsoft.com',
|
|
143
|
+
port: 443,
|
|
144
|
+
path: '/cognitiveservices/voices/list',
|
|
145
|
+
method: 'GET',
|
|
146
|
+
headers: {
|
|
147
|
+
'Ocp-Apim-Subscription-Key': node.credentials.mssubscriptionKey
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const reqAzure = httpsAzure.request(options, resVoices => {
|
|
151
|
+
var sChunkResponse = "";
|
|
152
|
+
resVoices.on('data', d => {
|
|
153
|
+
sChunkResponse += d.toString();
|
|
154
|
+
})
|
|
155
|
+
resVoices.on('end', () => {
|
|
156
|
+
try {
|
|
157
|
+
let oVoices = JSON.parse(sChunkResponse);
|
|
158
|
+
RED.log.info('ttsultimate-config: Microsoft Azure voices count: ' + oVoices.length);
|
|
159
|
+
for (let index = 0; index < oVoices.length; index++) {
|
|
160
|
+
const element = oVoices[index];
|
|
161
|
+
node.microsoftAzureTTSVoiceList.push({ name: element.ShortName + " (" + element.Gender + ")", id: element.ShortName })
|
|
162
|
+
}
|
|
163
|
+
} catch (error) {
|
|
164
|
+
RED.log.error('ttsultimate-config: listVoices: Error parsing Microsoft Azure TTS voices: ' + error.message);
|
|
165
|
+
node.microsoftAzureTTSVoiceList.push({ name: "Error parsing Microsoft Azure voices: " + error.message, id: "Ivy" });
|
|
166
|
+
}
|
|
167
|
+
})
|
|
168
|
+
})
|
|
169
|
+
reqAzure.on('error', error => {
|
|
170
|
+
RED.log.error('ttsultimate-config: listVoices: Error contacting Azure for getting the voices list: ' + error.message);
|
|
171
|
+
node.microsoftAzureTTSVoiceList.push({ name: "Error getting Microsoft Azure voices: " + error.message, id: "Ivy" })
|
|
172
|
+
reqAzure.end();
|
|
173
|
+
})
|
|
174
|
+
reqAzure.end();
|
|
175
|
+
};
|
|
176
|
+
RED.log.info("ttsultimate.config: Microsoft AzureTTS service enabled.")
|
|
177
|
+
try {
|
|
178
|
+
listVoicesAzure();
|
|
179
|
+
} catch (error) {
|
|
180
|
+
RED.log.error('ttsultimate-config: listVoices: Error getting Microsoft Azure voices: ' + error.message);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
} catch (error) {
|
|
184
|
+
RED.log.warn("ttsultimate.config: Microsoft AzureTTS service disabled. " + error.message)
|
|
185
|
+
}
|
|
186
|
+
// #########################################
|
|
187
|
+
|
|
99
188
|
//#endregion
|
|
100
189
|
|
|
101
190
|
|
|
@@ -313,6 +402,8 @@ module.exports = function (RED) {
|
|
|
313
402
|
RED.log.error('ttsultimate-config: listVoices: Error getting google Translate voices ' + error.message);
|
|
314
403
|
}
|
|
315
404
|
|
|
405
|
+
} else if (ttsservice === "microsoftazuretts") {
|
|
406
|
+
res.json(node.microsoftAzureTTSVoiceList);
|
|
316
407
|
}
|
|
317
408
|
});
|
|
318
409
|
|
|
@@ -531,7 +622,9 @@ module.exports = function (RED) {
|
|
|
531
622
|
RED.nodes.registerType("ttsultimate-config", TTSConfigNode, {
|
|
532
623
|
credentials: {
|
|
533
624
|
accessKey: { type: "text" },
|
|
534
|
-
secretKey: { type: "password" }
|
|
625
|
+
secretKey: { type: "password" },
|
|
626
|
+
mssubscriptionKey: { type: "text" },
|
|
627
|
+
mslocation: { type: "text" }
|
|
535
628
|
}
|
|
536
629
|
});
|
|
537
630
|
|
|
@@ -376,7 +376,7 @@ module.exports = function (RED) {
|
|
|
376
376
|
node.msg.connectionerror = false;
|
|
377
377
|
}
|
|
378
378
|
|
|
379
|
-
node.setNodeStatus({ fill: '
|
|
379
|
+
node.setNodeStatus({ fill: 'grey', shape: 'ring', text: 'Initialized.' });
|
|
380
380
|
|
|
381
381
|
|
|
382
382
|
|
|
@@ -399,8 +399,8 @@ module.exports = function (RED) {
|
|
|
399
399
|
|
|
400
400
|
if (_oTrack !== null) {
|
|
401
401
|
// Do some checks on the track.
|
|
402
|
-
if (_oTrack.hasOwnProperty("duration") && _oTrack.duration === 0 ||
|
|
403
|
-
|
|
402
|
+
if (_oTrack.hasOwnProperty("duration") && _oTrack.duration === 0 ||
|
|
403
|
+
(_oTrack.uri.startsWith("x-sonosprog-http") || _oTrack.uri.startsWith("x-sonosapi-hls-static") || _oTrack.uri.startsWith("x-sonos-spotify"))) {
|
|
404
404
|
// Stream
|
|
405
405
|
_oTrack.trackType = "stream";
|
|
406
406
|
} else if (_oTrack.hasOwnProperty("duration") && isNaN(_oTrack.duration)) {
|
|
@@ -566,6 +566,14 @@ module.exports = function (RED) {
|
|
|
566
566
|
slow: false // optional
|
|
567
567
|
};
|
|
568
568
|
data = await synthesizeSpeechGoogleTranslate(node.server.googleTranslateTTS, params);
|
|
569
|
+
} else if (node.server.ttsservice === "microsoftazuretts") {
|
|
570
|
+
node.setNodeStatus({ fill: 'green', shape: 'ring', text: 'Downloading from Microsoft Azure TTS...' });
|
|
571
|
+
// VoiceId is: code
|
|
572
|
+
const params = {
|
|
573
|
+
text: msg,
|
|
574
|
+
voice: node.voiceId
|
|
575
|
+
};
|
|
576
|
+
data = await synthesizeSpeechMicrosoftAzureTTS(node.server.microsoftAzureTTS, params);
|
|
569
577
|
}
|
|
570
578
|
// Save the downloaded file into the cache
|
|
571
579
|
fs.writeFileSync(sFileToBePlayed, data, function (error, result) {
|
|
@@ -988,6 +996,30 @@ module.exports = function (RED) {
|
|
|
988
996
|
}
|
|
989
997
|
};
|
|
990
998
|
|
|
999
|
+
// 12/10/2021 Microsoft Azure TTS Service
|
|
1000
|
+
async function synthesizeSpeechMicrosoftAzureTTS(ttsService, params) {
|
|
1001
|
+
|
|
1002
|
+
return new Promise(function (resolve, reject) {
|
|
1003
|
+
try {
|
|
1004
|
+
|
|
1005
|
+
// Microsoft fa sempre tutto diverso dagli altri, per cui mi tocca reinstanziare l'oggetto
|
|
1006
|
+
ttsService = node.server.setMicrosoftAzureVoice(params.voice);
|
|
1007
|
+
|
|
1008
|
+
ttsService.speakTextAsync(
|
|
1009
|
+
params.text,
|
|
1010
|
+
result => {
|
|
1011
|
+
ttsService.close();
|
|
1012
|
+
resolve (Buffer.from(result.audioData));
|
|
1013
|
+
},
|
|
1014
|
+
error => {
|
|
1015
|
+
ttsService.close();
|
|
1016
|
+
reject (error);
|
|
1017
|
+
});
|
|
1018
|
+
} catch (error) {
|
|
1019
|
+
reject (error);
|
|
1020
|
+
}
|
|
1021
|
+
});
|
|
1022
|
+
};
|
|
991
1023
|
|
|
992
1024
|
function getFilename(text, _sVoice, isSSML, extension, _speakingpitch, _speakingrate) {
|
|
993
1025
|
// Slug the text.
|