node-red-contrib-tts-ultimate 1.0.35 → 1.0.39
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/.vscode/launch.json +17 -0
- package/CHANGELOG.md +15 -0
- package/README.md +18 -8
- package/package.json +4 -3
- package/ttsultimate/ttsultimate-config.html +15 -4
- package/ttsultimate/ttsultimate-config.js +14 -13
- package/ttsultimate/ttsultimate.html +1 -1
- package/ttsultimate/ttsultimate.js +34 -29
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Usare IntelliSense per informazioni sui possibili attributi.
|
|
3
|
+
// Al passaggio del mouse vengono visualizzate le descrizioni degli attributi esistenti.
|
|
4
|
+
// Per altre informazioni, visitare: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
|
+
"version": "0.2.0",
|
|
6
|
+
"configurations": [
|
|
7
|
+
{
|
|
8
|
+
"type": "pwa-node",
|
|
9
|
+
"request": "launch",
|
|
10
|
+
"name": "Launch Program",
|
|
11
|
+
"skipFiles": [
|
|
12
|
+
"<node_internals>/**"
|
|
13
|
+
],
|
|
14
|
+
"program": "${workspaceFolder}/ttsultimate/ttsultimate.js"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.paypal.me/techtoday)
|
|
4
4
|
|
|
5
|
+
<p>
|
|
6
|
+
<b>Version 1.0.39</b> January 2022<br/>
|
|
7
|
+
- SSML: fixed an issue prevent using it.<br/>
|
|
8
|
+
- SSML: if SSML is enabled, the text auto split function is disabled, to avoid splitting SSML XML text.<br/>
|
|
9
|
+
- Microsoft Azure: update TTS engine to 1.19.0<br/>
|
|
10
|
+
- Google paid TTS: update TTS engine to 3.4.0<br/>
|
|
11
|
+
<p>
|
|
12
|
+
<b>Version 1.0.38</b> December 2021<br/>
|
|
13
|
+
- Removed some unwanted startup logs.<br/>
|
|
14
|
+
- Fixed ownfile sample code. Thanks to plats98.<br/>
|
|
15
|
+
<p>
|
|
16
|
+
<p>
|
|
17
|
+
<b>Version 1.0.36</b> November 2021<br/>
|
|
18
|
+
- NEW: Autosplit function: you can now set the maximum lenght of the text-parts, in case your spoken text is too long for the allowed TTS Engine limits.<br/>
|
|
19
|
+
<p>
|
|
5
20
|
<p>
|
|
6
21
|
<b>Version 1.0.35</b> October 2021<br/>
|
|
7
22
|
- NEW: You can force unmuting all players, then restore their previous state once finished playing.<br/>
|
package/README.md
CHANGED
|
@@ -125,6 +125,12 @@ On each deploy or node-red restart, delete all tts files in the cache. This is u
|
|
|
125
125
|
***Leave the TTS cache folder untouched*** (suggested only if you have enough disk space)<br/>
|
|
126
126
|
Don't delete the files cached. Useful if you wish to keep the tts files, even in case of internet outages, node-red restart or reboots.
|
|
127
127
|
<br/>
|
|
128
|
+
|
|
129
|
+
**Autosplit max length
|
|
130
|
+
<br/>
|
|
131
|
+
Due to some limitations in text lenght, applied by the online TTS Engines, TTS-Ultimate is capable to split your long text to be spoken, in shorter texts in an intelligent way.<br/>
|
|
132
|
+
This field allow you to set the maximum lenght (**in chars**) of each splitted text part. The default is **220** and is OK for most cases. You can change this valut to whatever you want but keep in mind, that your TTS engine can either cut the text or return an error, if the text is too long. As the cached filename is equal to the text being spoken, you could also hit the maximum filename lenght of your filesystem. So keep the default value, unless you absolute need to change it.<br/>
|
|
133
|
+
<br/>
|
|
128
134
|
<br/>
|
|
129
135
|
|
|
130
136
|
# TTS-ULTIMATE NODE
|
|
@@ -266,17 +272,19 @@ The property is a JSON object.
|
|
|
266
272
|
<img src='https://github.com/Supergiovane/node-red-contrib-tts-ultimate/raw/master/img/setConfig.png' width="80%">
|
|
267
273
|
|
|
268
274
|
**msg.setConfig**<br/>
|
|
269
|
-
This is the property where you can set all the things. It must be
|
|
275
|
+
This is the property where you can set all the things. It must be a JSON Object with the below specified properties.<br/>
|
|
276
|
+
The setting is retained until the node receives another msg.setConfig or until node-red is restarted.<br/>
|
|
270
277
|
|
|
271
|
-
**setMainPlayerIP**<br/>
|
|
272
|
-
Sets the main player IP. This will also be the coordinator if you have a group of players
|
|
278
|
+
> **property setMainPlayerIP**<br/>
|
|
279
|
+
Sets the main player IP. This will also be the coordinator if you have a group of players.
|
|
273
280
|
|
|
274
|
-
**setPlayerGroupArray**<br/>
|
|
275
|
-
Sets the array of players beloging to the group, if any.<br/>
|
|
276
|
-
If you have only one additional player, you need to ever put it into an array. See below.
|
|
281
|
+
> **property setPlayerGroupArray**<br/>
|
|
282
|
+
Sets the array of players beloging to the group, if any.<br/>
|
|
283
|
+
If you have only one additional player, you need to ever put it into an array. See below.
|
|
277
284
|
|
|
278
285
|
```js
|
|
279
|
-
// Set player IP
|
|
286
|
+
// Set main player IP
|
|
287
|
+
// The setting is retained until the node receives another msg.setConfig or until node-red is restarted.
|
|
280
288
|
var config= {
|
|
281
289
|
setMainPlayerIP:"192.168.1.109"
|
|
282
290
|
};
|
|
@@ -286,6 +294,7 @@ return msg;
|
|
|
286
294
|
|
|
287
295
|
```js
|
|
288
296
|
// Set player IP and additional players
|
|
297
|
+
// The setting is retained until the node receives another msg.setConfig or until node-red is restarted.
|
|
289
298
|
var config= {
|
|
290
299
|
setMainPlayerIP:"192.168.1.109",
|
|
291
300
|
setPlayerGroupArray:[
|
|
@@ -300,6 +309,7 @@ return msg;
|
|
|
300
309
|
|
|
301
310
|
```js
|
|
302
311
|
// If you have only one additional player
|
|
312
|
+
// The setting is retained until the node receives another msg.setConfig or until node-red is restarted.
|
|
303
313
|
var config= {
|
|
304
314
|
setMainPlayerIP:"192.168.1.109",
|
|
305
315
|
setPlayerGroupArray:["192.168.1.110"]
|
|
@@ -333,7 +343,7 @@ return msg;
|
|
|
333
343
|
> Adjust the nodes according to your setup
|
|
334
344
|
|
|
335
345
|
```js
|
|
336
|
-
[{"id":"db0ea33.f1186e","type":"ttsultimate","z":"c6efd2b6.ab02e8","name":"","voice":"en-AU-Standard-A#en-AU#FEMALE","ssml":false,"sonosipaddress":"192.168.1.109","sonosvolume":"25","sonoshailing":"Hailing_Hailing.mp3","config":"4f941d61.f52c4c","propertyType":{},"rules":[],"x":670,"y":240,"wires":[[]]},{"id":"c7fb2970.271978","type":"
|
|
346
|
+
[{"id":"db0ea33.f1186e","type":"ttsultimate","z":"c6efd2b6.ab02e8","name":"","voice":"en-AU-Standard-A#en-AU#FEMALE","ssml":false,"sonosipaddress":"192.168.1.109","sonosvolume":"25","sonoshailing":"Hailing_Hailing.mp3","config":"4f941d61.f52c4c","propertyType":{},"rules":[],"x":670,"y":240,"wires":[[]]},{"id":"c7fb2970.271978","type":"ownfileultimate","z":"c6efd2b6.ab02e8","name":"","selectedFile":"OwnFile_Tur geoeffnet.mp3","x":490,"y":220,"wires":[["db0ea33.f1186e"]]},{"id":"fef80c5b.49f9e","type":"inject","z":"c6efd2b6.ab02e8","name":"","topic":"","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":220,"wires":[["c7fb2970.271978"]]},{"id":"807f0f6c.6d59c","type":"comment","z":"c6efd2b6.ab02e8","name":"You can upload your own voice messages and use it with ttsultimate","info":"","x":310,"y":180,"wires":[]},{"id":"536e58b3.bb8468","type":"ownfileultimate","z":"c6efd2b6.ab02e8","name":"","selectedFile":"OwnFile_Tur geoeffnet.mp3","x":490,"y":260,"wires":[["db0ea33.f1186e"]]},{"id":"26c339f9.346fbe","type":"inject","z":"c6efd2b6.ab02e8","name":"","topic":"","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":260,"wires":[["25016441.6447bc"]]},{"id":"25016441.6447bc","type":"function","z":"c6efd2b6.ab02e8","name":"Dynamically Select file","func":"// Override the selected file.\nmsg.selectedFile=\"Porta aperta\"\nreturn msg;","outputs":1,"noerr":0,"x":300,"y":260,"wires":[["536e58b3.bb8468"]]},{"id":"4f941d61.f52c4c","type":"ttsultimate-config","z":"","name":"GoogleTTS","noderedipaddress":"192.168.1.219","noderedport":"1980","purgediratrestart":"leave","ttsservice":"googletts"}]
|
|
337
347
|
```
|
|
338
348
|
</details>
|
|
339
349
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-red-contrib-tts-ultimate",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.39",
|
|
4
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": {
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"google",
|
|
17
17
|
"voice",
|
|
18
18
|
"amazon",
|
|
19
|
+
"azure",
|
|
19
20
|
"tts",
|
|
20
21
|
"sonos",
|
|
21
22
|
"IOT",
|
|
@@ -45,9 +46,9 @@
|
|
|
45
46
|
"formidable": "1.2.2",
|
|
46
47
|
"os": ">=0.1.1",
|
|
47
48
|
"path": ">=0.12.7",
|
|
48
|
-
"@google-cloud/text-to-speech": "3.
|
|
49
|
+
"@google-cloud/text-to-speech": "3.4.0",
|
|
49
50
|
"google-translate-tts": ">=0.2.1",
|
|
50
|
-
"microsoft-cognitiveservices-speech-sdk": ">=1.
|
|
51
|
+
"microsoft-cognitiveservices-speech-sdk": ">=1.19.0"
|
|
51
52
|
},
|
|
52
53
|
"devDependencies": {
|
|
53
54
|
"eslint": ">=4.18.2",
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
type: "text"
|
|
18
18
|
},
|
|
19
19
|
purgediratrestart: { value: "leave", required: false },
|
|
20
|
-
ttsservice: { value: "googletranslate", required: false }
|
|
20
|
+
ttsservice: { value: "googletranslate", required: false },
|
|
21
|
+
limitTTSFilenameLenght: { value: 220, required: false, validate: RED.validators.number() }
|
|
21
22
|
|
|
22
23
|
},
|
|
23
24
|
credentials: {
|
|
@@ -32,6 +33,10 @@
|
|
|
32
33
|
oneditprepare: function () {
|
|
33
34
|
var node = this;
|
|
34
35
|
|
|
36
|
+
// 01/11/2021
|
|
37
|
+
//if (node.limitTTSFilenameLenght === undefined) {
|
|
38
|
+
// $("#node-config-input-limitTTSFilenameLenght").val(220);
|
|
39
|
+
//}
|
|
35
40
|
// 21/03/2020 Check if the node is the absolute first in the flow. In this case, it has no http server instatiaced
|
|
36
41
|
$.getJSON('ttsultimateGetEthAddress', (data) => {
|
|
37
42
|
$("#pleaseDeploy").hide();
|
|
@@ -61,16 +66,16 @@
|
|
|
61
66
|
$("#node-config-input-ttsservice").change(function (e) {
|
|
62
67
|
if ($("#node-config-input-ttsservice").val() == "polly") {
|
|
63
68
|
$("#GoogleForm").hide();
|
|
64
|
-
$("#microsoftAzureForm").hide();
|
|
69
|
+
$("#microsoftAzureForm").hide();
|
|
65
70
|
$("#pollyForm").show();
|
|
66
71
|
} else if ($("#node-config-input-ttsservice").val() == "googletts") {
|
|
67
|
-
$("#microsoftAzureForm").hide();
|
|
72
|
+
$("#microsoftAzureForm").hide();
|
|
68
73
|
$("#pollyForm").hide();
|
|
69
74
|
$("#GoogleForm").show();
|
|
70
75
|
} else if ($("#node-config-input-ttsservice").val() == "googletranslate") {
|
|
71
76
|
$("#pollyForm").hide();
|
|
72
77
|
$("#GoogleForm").hide();
|
|
73
|
-
$("#microsoftAzureForm").hide();
|
|
78
|
+
$("#microsoftAzureForm").hide();
|
|
74
79
|
} else if ($("#node-config-input-ttsservice").val() == "microsoftazuretts") {
|
|
75
80
|
$("#pollyForm").hide();
|
|
76
81
|
$("#GoogleForm").hide();
|
|
@@ -208,6 +213,12 @@
|
|
|
208
213
|
<option value="leave">Leave the TTS cache folder untouched (not suggested if you have less disk space)</option>
|
|
209
214
|
</select>
|
|
210
215
|
</div>
|
|
216
|
+
|
|
217
|
+
<div class="form-row">
|
|
218
|
+
<label for="node-config-input-limitTTSFilenameLenght"><i class="fa fa-file"></i> Autosplit max length (chars)</label>
|
|
219
|
+
<input type="text" id="node-config-input-limitTTSFilenameLenght">
|
|
220
|
+
</div>
|
|
221
|
+
|
|
211
222
|
</div>
|
|
212
223
|
|
|
213
224
|
</script>
|
|
@@ -23,6 +23,7 @@ module.exports = function (RED) {
|
|
|
23
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)
|
|
24
24
|
node.whoIsUsingTheServer = ""; // Client node.id using the server, because only a ttsultimate node can use the serve at once.
|
|
25
25
|
node.ttsservice = config.ttsservice || "googletranslate";
|
|
26
|
+
node.limitTTSFilenameLenght = config.limitTTSFilenameLenght === undefined ? 220 : config.limitTTSFilenameLenght;
|
|
26
27
|
// node.polly = null;
|
|
27
28
|
// node.googleTTS = null;
|
|
28
29
|
// node.googleTranslateTTS = null;
|
|
@@ -96,7 +97,7 @@ module.exports = function (RED) {
|
|
|
96
97
|
RED.log.warn("ttsultimate-config " + node.id + ": Polly service disabled. " + error.message)
|
|
97
98
|
}
|
|
98
99
|
} else {
|
|
99
|
-
RED.log.
|
|
100
|
+
//RED.log.info("ttsultimate-config " + node.id + ": Polly service not used.");
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
|
|
@@ -117,7 +118,7 @@ module.exports = function (RED) {
|
|
|
117
118
|
}
|
|
118
119
|
|
|
119
120
|
} else {
|
|
120
|
-
RED.log.
|
|
121
|
+
// RED.log.info("ttsultimate-config " + node.id + ": Google TTS service not used.");
|
|
121
122
|
}
|
|
122
123
|
|
|
123
124
|
|
|
@@ -127,10 +128,10 @@ module.exports = function (RED) {
|
|
|
127
128
|
try {
|
|
128
129
|
node.googleTranslateTTS = GoogleTranslate;
|
|
129
130
|
} catch (error) {
|
|
130
|
-
RED.log.
|
|
131
|
+
//RED.log.info("ttsultimate-config " + node.id + ": Google Translate free service not used.");
|
|
131
132
|
}
|
|
132
133
|
} else {
|
|
133
|
-
RED.log.
|
|
134
|
+
//RED.log.info("ttsultimate-config " + node.id + ": Google Translate free service not used.");
|
|
134
135
|
}
|
|
135
136
|
|
|
136
137
|
|
|
@@ -179,13 +180,13 @@ module.exports = function (RED) {
|
|
|
179
180
|
}
|
|
180
181
|
} catch (error) {
|
|
181
182
|
RED.log.error('ttsultimate-config ' + node.id + ': listVoices: Error parsing Microsoft Azure TTS voices: ' + error.message);
|
|
182
|
-
node.microsoftAzureTTSVoiceList.push({ name: "Error parsing Microsoft Azure voices: " + error.message, id: "Ivy" });
|
|
183
|
+
node.microsoftAzureTTSVoiceList.push({ name: "Error parsing Microsoft Azure voices: " + error.message + " Check cretentials, deploy and restart node-red.", id: "Ivy" });
|
|
183
184
|
}
|
|
184
185
|
})
|
|
185
186
|
})
|
|
186
187
|
reqAzure.on('error', error => {
|
|
187
188
|
RED.log.error('ttsultimate-config ' + node.id + ': listVoices: Error contacting Azure for getting the voices list: ' + error.message);
|
|
188
|
-
node.microsoftAzureTTSVoiceList.push({ name: "Error getting Microsoft Azure voices: " + error.message, id: "Ivy" })
|
|
189
|
+
node.microsoftAzureTTSVoiceList.push({ name: "Error getting Microsoft Azure voices: " + error.message + " Check cretentials, deploy and restart node-red.", id: "Ivy" })
|
|
189
190
|
reqAzure.end();
|
|
190
191
|
})
|
|
191
192
|
reqAzure.end();
|
|
@@ -201,7 +202,7 @@ module.exports = function (RED) {
|
|
|
201
202
|
RED.log.warn("ttsultimate-config " + node.id + ": Microsoft AzureTTS service disabled. " + error.message)
|
|
202
203
|
}
|
|
203
204
|
} else {
|
|
204
|
-
RED.log.
|
|
205
|
+
//RED.log.info("ttsultimate-config " + node.id + ": Microsoft AzureTTS service not used. ");
|
|
205
206
|
}
|
|
206
207
|
// #########################################
|
|
207
208
|
|
|
@@ -364,7 +365,7 @@ module.exports = function (RED) {
|
|
|
364
365
|
node.polly.describeVoices(jfiltroVoci, function (err, data) {
|
|
365
366
|
if (err) {
|
|
366
367
|
RED.log.warn('ttsultimate-config ' + node.id + ': Error getting polly voices ' + err);
|
|
367
|
-
jListVoices.push({ name: "Error retrieving voices. " + err, id: "Ivy" })
|
|
368
|
+
jListVoices.push({ name: "Error retrieving voices. " + err + " Check cretentials, deploy and restart node-red.", id: "Ivy" })
|
|
368
369
|
res.json(jListVoices)
|
|
369
370
|
} else {
|
|
370
371
|
for (let index = 0; index < data.Voices.length; index++) {
|
|
@@ -391,15 +392,15 @@ module.exports = function (RED) {
|
|
|
391
392
|
});
|
|
392
393
|
res.json(jListVoices)
|
|
393
394
|
} catch (error) {
|
|
394
|
-
RED.log.error('ttsultimate-config ' + node.id + ': Error getting google TTS voices ' + error.message);
|
|
395
|
-
jListVoices.push({ name: "Error getting Google TTS voices. " + error.message, id: "Ivy" })
|
|
395
|
+
RED.log.error('ttsultimate-config ' + node.id + ': Error getting google TTS voices ' + error.message + " Please deploy and restart node-red.");
|
|
396
|
+
jListVoices.push({ name: "Error getting Google TTS voices. " + error.message + " Check credentials, deploy and restart node-red.", id: "Ivy" })
|
|
396
397
|
res.json(jListVoices)
|
|
397
398
|
}
|
|
398
399
|
};
|
|
399
400
|
try {
|
|
400
401
|
listVoices();
|
|
401
402
|
} catch (error) {
|
|
402
|
-
RED.log.error('ttsultimate-config ' + node.id + ': listVoices: Error getting google TTS voices ' + error.message);
|
|
403
|
+
RED.log.error('ttsultimate-config ' + node.id + ': listVoices: Error getting google TTS voices ' + error.message + " Please deploy and restart node-red.");
|
|
403
404
|
}
|
|
404
405
|
|
|
405
406
|
} else if (ttsservice === "googletranslate") {
|
|
@@ -412,14 +413,14 @@ module.exports = function (RED) {
|
|
|
412
413
|
res.json(jListVoices)
|
|
413
414
|
} catch (error) {
|
|
414
415
|
RED.log.error('ttsultimate-config ' + node.id + ': Error getting google Translate voices ' + error.message);
|
|
415
|
-
jListVoices.push({ name: "Error getting Google Translate voices. " + error.message, id: "Ivy" })
|
|
416
|
+
jListVoices.push({ name: "Error getting Google Translate voices. " + error.message + " Deploy and restart node-red.", id: "Ivy" })
|
|
416
417
|
res.json(jListVoices)
|
|
417
418
|
}
|
|
418
419
|
};
|
|
419
420
|
try {
|
|
420
421
|
listVoices();
|
|
421
422
|
} catch (error) {
|
|
422
|
-
RED.log.error('ttsultimate-config ' + node.id + ': listVoices: Error getting google Translate voices ' + error.message);
|
|
423
|
+
RED.log.error('ttsultimate-config ' + node.id + ': listVoices: Error getting google Translate voices ' + error.message + " Please deploy and restart node-red.");
|
|
423
424
|
}
|
|
424
425
|
|
|
425
426
|
} else if (ttsservice === "microsoftazuretts") {
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
</div>
|
|
40
40
|
<div class="form-row">
|
|
41
41
|
<label></label>
|
|
42
|
-
<input type="checkbox" id="node-input-ssml" style="margin-left: 0px; vertical-align: top; width: auto !important;"> <label style="width:auto !important;"> Enable SSML</label>
|
|
42
|
+
<input type="checkbox" id="node-input-ssml" style="margin-left: 0px; vertical-align: top; width: auto !important;"> <label style="width:auto !important;"> Enable SSML (unsupported by Google without authentication)</label>
|
|
43
43
|
</div>
|
|
44
44
|
<div class="form-row">
|
|
45
45
|
<label for="node-input-sonoshailing"><i class="fa fa-bell"></i> Hailing</label>
|
|
@@ -591,11 +591,11 @@ module.exports = function (RED) {
|
|
|
591
591
|
voice: { name: node.voiceId.split("#")[0], languageCode: node.voiceId.split("#")[1], ssmlGender: node.voiceId.split("#")[2] },
|
|
592
592
|
audioConfig: { audioEncoding: "MP3", speakingRate: parseFloat(node.speakingrate), pitch: parseFloat(node.speakingpitch), },
|
|
593
593
|
};
|
|
594
|
-
params.input = node.ssml ===
|
|
594
|
+
params.input = node.ssml === false ? { text: msg } : { ssml: msg };
|
|
595
595
|
data = await synthesizeSpeechGoogleTTS([node.server.googleTTS, params]);
|
|
596
596
|
} else if (node.server.ttsservice === "googletranslate") {
|
|
597
597
|
node.setNodeStatus({ fill: 'green', shape: 'ring', text: 'Downloading from Google Translate...' });
|
|
598
|
-
// VoiceId is: code
|
|
598
|
+
// VoiceId is: code. SSML is not supported by google translate
|
|
599
599
|
const params = {
|
|
600
600
|
text: msg,
|
|
601
601
|
voice: node.voiceId,
|
|
@@ -941,36 +941,41 @@ module.exports = function (RED) {
|
|
|
941
941
|
}
|
|
942
942
|
// ########################
|
|
943
943
|
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
944
|
+
// 03/01/2022 if ssml is enabled, disable the auto split function
|
|
945
|
+
if (!node.ssml) {
|
|
946
|
+
// SSML disabled
|
|
947
|
+
// 30/01/2021 split the text if it's too long, otherwies i'll have issues with filename too long.
|
|
948
|
+
if (msg.payload.length >= node.server.limitTTSFilenameLenght) {
|
|
949
|
+
let sTemp = "";
|
|
950
|
+
let aSeps = [".", ",", ":", ";", "!", "?"];
|
|
951
|
+
let sPayload = msg.payload.replace(/[\r\n]+/gm, "");
|
|
952
|
+
for (let index = 0; index < sPayload.length; index++) {
|
|
953
|
+
const element = sPayload.substr(index, 1);
|
|
954
|
+
sTemp += element;
|
|
955
|
+
if (aSeps.indexOf(element) > -1 && sTemp.length > 20) {
|
|
956
|
+
const oMsg = RED.util.cloneMessage(msg);
|
|
957
|
+
oMsg.payload = sTemp;
|
|
958
|
+
node.tempMSGStorage.push(oMsg);
|
|
959
|
+
sTemp = "";
|
|
960
|
+
}
|
|
961
|
+
if (sTemp.length > node.server.limitTTSFilenameLenght && element === " ") {
|
|
962
|
+
// Split using space
|
|
963
|
+
const oMsg = RED.util.cloneMessage(msg);
|
|
964
|
+
oMsg.payload = sTemp;
|
|
965
|
+
node.tempMSGStorage.push(oMsg);
|
|
966
|
+
sTemp = "";
|
|
967
|
+
}
|
|
966
968
|
}
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
node.tempMSGStorage.push(oMsg);
|
|
969
|
+
// Remaining
|
|
970
|
+
const oMsg = RED.util.cloneMessage(msg);
|
|
971
|
+
oMsg.payload = sTemp;
|
|
972
|
+
node.tempMSGStorage.push(oMsg);
|
|
972
973
|
|
|
974
|
+
} else {
|
|
975
|
+
node.tempMSGStorage.push(msg);
|
|
976
|
+
}
|
|
973
977
|
} else {
|
|
978
|
+
// SSML enabled
|
|
974
979
|
node.tempMSGStorage.push(msg);
|
|
975
980
|
}
|
|
976
981
|
|