node-red-contrib-tts-ultimate 2.0.4 → 2.0.5
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/package.json +1 -1
- package/ttsultimate/ttsultimate.js +52 -88
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.paypal.me/techtoday)
|
|
4
4
|
|
|
5
|
+
<p>
|
|
6
|
+
<b>Version 2.0.5</b> October 2023<br/>
|
|
7
|
+
- Speed up emitting msg, when not using Sonos.<br/>
|
|
8
|
+
</p>
|
|
5
9
|
<p>
|
|
6
10
|
<b>Version 2.0.4</b> August 2023<br/>
|
|
7
11
|
- Removed unused new AWS api.<br/>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-red-contrib-tts-ultimate",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.5",
|
|
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, ElevenLabs.io TTS 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": {
|
|
@@ -369,7 +369,7 @@ module.exports = function (RED) {
|
|
|
369
369
|
// 27/11/2019 Check Sonos connection health
|
|
370
370
|
|
|
371
371
|
node.CheckSonosConnection = () => {
|
|
372
|
-
if (node.playertype
|
|
372
|
+
if (node.playertype === "sonos") {
|
|
373
373
|
node.SonosClient.getCurrentState().then(state => {
|
|
374
374
|
|
|
375
375
|
// 11/12/202020 The connection with Sonos is OK.
|
|
@@ -392,7 +392,7 @@ module.exports = function (RED) {
|
|
|
392
392
|
node.oTimerSonosConnectionCheck = setTimeout(function () { node.CheckSonosConnection(); }, 10000);
|
|
393
393
|
});
|
|
394
394
|
} else {
|
|
395
|
-
node.setNodeStatus({ fill: "green", shape: "dot", text: "
|
|
395
|
+
node.setNodeStatus({ fill: "green", shape: "dot", text: "Ready." });
|
|
396
396
|
node.msg.connectionerror = false;
|
|
397
397
|
node.send([null, { payload: node.msg.connectionerror }]);
|
|
398
398
|
}
|
|
@@ -417,8 +417,6 @@ module.exports = function (RED) {
|
|
|
417
417
|
node.oAdditionalSonosPlayers.push({ oPlayer: new sonos.Sonos(element.host), hostVolumeAdjust: Number(element.hostVolumeAdjust) });
|
|
418
418
|
RED.log.info("ttsultimate: FOUND ADDITIONAL PLAYER " + element.host + " Adjusted volume: " + element.hostVolumeAdjust);
|
|
419
419
|
}
|
|
420
|
-
|
|
421
|
-
|
|
422
420
|
// 27/11/2019 Start the connection healty check
|
|
423
421
|
node.oTimerSonosConnectionCheck = setTimeout(function () { node.CheckSonosConnection(); }, 5000);
|
|
424
422
|
} else if (node.playertype === "noplayer") {
|
|
@@ -427,7 +425,6 @@ module.exports = function (RED) {
|
|
|
427
425
|
|
|
428
426
|
node.setNodeStatus({ fill: 'grey', shape: 'ring', text: 'Initialized.' });
|
|
429
427
|
|
|
430
|
-
|
|
431
428
|
// 22/09/2020 Flush Queue and set to stopped
|
|
432
429
|
node.flushQueue = () => {
|
|
433
430
|
// 10/04/2018 Remove the TTS message from the queue
|
|
@@ -439,8 +436,6 @@ module.exports = function (RED) {
|
|
|
439
436
|
if (node.server.whoIsUsingTheServer === node.id) node.server.whoIsUsingTheServer = "";
|
|
440
437
|
}
|
|
441
438
|
|
|
442
|
-
|
|
443
|
-
|
|
444
439
|
// 30/12/2020 Supergiovane resume queue for radio, queue music, TV in , line in etc.
|
|
445
440
|
async function resumeMusicQueue(_oTrack, _oPlayer = node.SonosClient) {
|
|
446
441
|
|
|
@@ -526,43 +521,46 @@ module.exports = function (RED) {
|
|
|
526
521
|
let t = setTimeout(() => { return true; }, 5000); // Wait some seconds
|
|
527
522
|
};
|
|
528
523
|
|
|
529
|
-
|
|
530
524
|
// Handle the queue
|
|
531
525
|
async function HandleQueue() {
|
|
532
526
|
node.bBusyPlayingQueue = true;
|
|
533
527
|
node.server.whoIsUsingTheServer = node.id; // Signal to other ttsultimate node, that i'm using the Sonos device
|
|
534
528
|
try {
|
|
535
529
|
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
530
|
+
if (node.playertype !== "noplayer") {
|
|
531
|
+
// Get the current music queue, if one
|
|
532
|
+
var oCurTrack = null;
|
|
533
|
+
try {
|
|
534
|
+
oCurTrack = await getMusicQueue();
|
|
535
|
+
// 19/04/2022 The current track of additional players is read in the groupSpeakerySync function
|
|
536
|
+
} catch (error) {
|
|
537
|
+
oCurTrack = null;
|
|
538
|
+
}
|
|
544
539
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
540
|
+
// 05/12/2020 Set "completed" to false and send it
|
|
541
|
+
node.msg.completed = false;
|
|
542
|
+
try {
|
|
543
|
+
await groupSpeakersSync(); // 20/03/2020 Group Speakers toghether and reads each current track
|
|
544
|
+
} catch (error) {
|
|
545
|
+
// Don't care.
|
|
546
|
+
node.setNodeStatus({ fill: "red", shape: "ring", text: "Error grouping speakers: " + error.message });
|
|
547
|
+
RED.log.error("ttsultimate: Error grouping speakers: " + error.message);
|
|
548
|
+
}
|
|
554
549
|
|
|
555
|
-
|
|
550
|
+
node.send([{ passThroughMessage: node.passThroughMessage, payload: node.msg.completed }, null]);
|
|
556
551
|
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
552
|
+
// 24/08/2021 If something was playing, stop the player https://github.com/Supergiovane/node-red-contrib-tts-ultimate/issues/32
|
|
553
|
+
try {
|
|
554
|
+
//await node.SonosClient.stop(); //.then(result => {
|
|
555
|
+
await STOPSync();
|
|
556
|
+
} catch (error) {
|
|
557
|
+
//RED.log.error("ttsultimate: Error stopping in HandleSend: " + error.message);
|
|
558
|
+
}
|
|
559
|
+
} else {
|
|
560
|
+
node.msg.completed = false;
|
|
561
|
+
node.send([{ passThroughMessage: node.passThroughMessage, payload: node.msg.completed }, null]);
|
|
563
562
|
}
|
|
564
563
|
|
|
565
|
-
|
|
566
564
|
while (node.tempMSGStorage.length > 0) {
|
|
567
565
|
node.currentMSGbeingSpoken = node.tempMSGStorage.shift()//node.tempMSGStorage[0];// Advise the whole node of the currently spoken MSG
|
|
568
566
|
const msg = node.currentMSGbeingSpoken.payload.toString(); // Get the text to be spoken
|
|
@@ -874,20 +872,19 @@ module.exports = function (RED) {
|
|
|
874
872
|
node.send([{ passThroughMessage: node.passThroughMessage, payload: node.msg.completed }, null]);
|
|
875
873
|
node.bBusyPlayingQueue = false
|
|
876
874
|
node.server.whoIsUsingTheServer = ""; // Signal to other ttsultimate node, that i'm not using the Sonos device anymore
|
|
877
|
-
},
|
|
875
|
+
}, 500)
|
|
878
876
|
|
|
879
877
|
} else if (node.playertype === "noplayer") {
|
|
880
878
|
// End task if no player is selected.
|
|
881
879
|
// Output the array of files
|
|
882
|
-
|
|
883
880
|
// Signal end playing
|
|
884
|
-
let t = setTimeout(() => {
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
}, 1000)
|
|
881
|
+
//let t = setTimeout(() => {
|
|
882
|
+
node.msg.completed = true;
|
|
883
|
+
node.currentMSGbeingSpoken = {};
|
|
884
|
+
node.send([{ passThroughMessage: node.passThroughMessage, payload: node.msg.completed, filesArray: noPlayerFileArray }, null]);
|
|
885
|
+
node.bBusyPlayingQueue = false
|
|
886
|
+
node.server.whoIsUsingTheServer = ""; // Signal to other ttsultimate node, that i'm not using the Sonos device anymore
|
|
887
|
+
//}, 1000)
|
|
891
888
|
}
|
|
892
889
|
|
|
893
890
|
} catch (error) {
|
|
@@ -1028,14 +1025,18 @@ module.exports = function (RED) {
|
|
|
1028
1025
|
// There is already a priority message being spoken, do nothing
|
|
1029
1026
|
node.setNodeStatus({ fill: 'grey', shape: 'ring', text: 'There is already a priority message being spoken...queuing' });
|
|
1030
1027
|
} else {
|
|
1031
|
-
node.
|
|
1032
|
-
node.
|
|
1028
|
+
if (node.playertype !== 'noplayer') {
|
|
1029
|
+
node.SonosClient.stop().then(result => {
|
|
1030
|
+
node.bTimeOutPlay = true;
|
|
1031
|
+
node.currentMSGbeingSpoken = msg; // Set immediately, otherwise if comes new flow messages, currentMSGbeingSpoken is too old.
|
|
1032
|
+
}).catch(err => {
|
|
1033
|
+
// Don't care
|
|
1034
|
+
node.bTimeOutPlay = true;
|
|
1035
|
+
node.currentMSGbeingSpoken = msg;// Set immediately, otherwise if comes new flow messages, currentMSGbeingSpoken is too old.
|
|
1036
|
+
})
|
|
1037
|
+
} else {
|
|
1033
1038
|
node.currentMSGbeingSpoken = msg; // Set immediately, otherwise if comes new flow messages, currentMSGbeingSpoken is too old.
|
|
1034
|
-
}
|
|
1035
|
-
// Don't care
|
|
1036
|
-
node.bTimeOutPlay = true;
|
|
1037
|
-
node.currentMSGbeingSpoken = msg;// Set immediately, otherwise if comes new flow messages, currentMSGbeingSpoken is too old.
|
|
1038
|
-
})
|
|
1039
|
+
}
|
|
1039
1040
|
}
|
|
1040
1041
|
|
|
1041
1042
|
} else {
|
|
@@ -1047,44 +1048,6 @@ module.exports = function (RED) {
|
|
|
1047
1048
|
}
|
|
1048
1049
|
// ########################
|
|
1049
1050
|
|
|
1050
|
-
// // 03/01/2022 if ssml is enabled, disable the auto split function
|
|
1051
|
-
// if (!node.ssml) {
|
|
1052
|
-
// // SSML disabled
|
|
1053
|
-
// // 30/01/2021 split the text if it's too long, otherwies i'll have issues with filename too long.
|
|
1054
|
-
// if (msg.payload.length >= node.server.limitTTSFilenameLenght) {
|
|
1055
|
-
// let sTemp = "";
|
|
1056
|
-
// let aSeps = [".", ",", ":", ";", "!", "?"];
|
|
1057
|
-
// let sPayload = msg.payload.replace(/[\r\n]+/gm, "");
|
|
1058
|
-
// for (let index = 0; index < sPayload.length; index++) {
|
|
1059
|
-
// const element = sPayload.substr(index, 1);
|
|
1060
|
-
// sTemp += element;
|
|
1061
|
-
// if (aSeps.indexOf(element) > -1 && sTemp.length > 20) {
|
|
1062
|
-
// const oMsg = RED.util.cloneMessage(msg);
|
|
1063
|
-
// oMsg.payload = sTemp;
|
|
1064
|
-
// node.tempMSGStorage.push(oMsg);
|
|
1065
|
-
// sTemp = "";
|
|
1066
|
-
// }
|
|
1067
|
-
// if (sTemp.length > node.server.limitTTSFilenameLenght && element === " ") {
|
|
1068
|
-
// // Split using space
|
|
1069
|
-
// const oMsg = RED.util.cloneMessage(msg);
|
|
1070
|
-
// oMsg.payload = sTemp;
|
|
1071
|
-
// node.tempMSGStorage.push(oMsg);
|
|
1072
|
-
// sTemp = "";
|
|
1073
|
-
// }
|
|
1074
|
-
// }
|
|
1075
|
-
// // Remaining
|
|
1076
|
-
// const oMsg = RED.util.cloneMessage(msg);
|
|
1077
|
-
// oMsg.payload = sTemp;
|
|
1078
|
-
// node.tempMSGStorage.push(oMsg);
|
|
1079
|
-
|
|
1080
|
-
// } else {
|
|
1081
|
-
// node.tempMSGStorage.push(msg);
|
|
1082
|
-
// }
|
|
1083
|
-
// } else {
|
|
1084
|
-
// // SSML enabled
|
|
1085
|
-
// node.tempMSGStorage.push(msg);
|
|
1086
|
-
// }
|
|
1087
|
-
|
|
1088
1051
|
// Starts main queue watching
|
|
1089
1052
|
node.tempMSGStorage.push(msg);
|
|
1090
1053
|
node.waitForQueue();
|
|
@@ -1107,7 +1070,8 @@ module.exports = function (RED) {
|
|
|
1107
1070
|
node.setNodeStatus({ fill: 'yellow', shape: 'ring', text: "Sonos is occupied by " + node.server.whoIsUsingTheServer + " Retry..." });
|
|
1108
1071
|
}
|
|
1109
1072
|
node.waitForQueue();
|
|
1110
|
-
}, 1000);
|
|
1073
|
+
}, node.playertype === "noplayer" ? 100 : 1000);
|
|
1074
|
+
|
|
1111
1075
|
}
|
|
1112
1076
|
|
|
1113
1077
|
node.on('close', function (done) {
|