node-red-contrib-tts-ultimate
Version:
Transforms the text in speech and hear it using Sonos, Google Cast (Chromecast / Nest) or DLNA/UPnP players, or generate an audio file to be used with third parties nodes. Works with voices from Google (without credentials as well), Google TTS, ElevenLabs
295 lines (253 loc) • 14.5 kB
HTML
<script type="text/javascript">
RED.nodes.registerType("ttsultimate-config", {
category: 'config',
defaults:
{
name: { value: "TTS Service" },
noderedipaddress:
{
value: "AUTODISCOVER",
required: false,
type: "text"
},
noderedport:
{
value: "1980",
required: false,
type: "text"
},
purgediratrestart: { value: "leave", required: false },
ttsservice: { value: "googletranslate", required: false },
TTSRootFolderPath: { value: "", required: false }
},
credentials: {
elevenlabsKey: { type: "text" },
voiceaiKey: { type: "text" }
},
label: function () {
return this.name || "";
},
oneditprepare: function () {
var node = this;
// 21/03/2020 Check if the node is the absolute first in the flow. In this case, it has no http server instatiaced
// $.getJSON('ttsultimateGetEthAddress', (data) => {
$("#pleaseDeploy").hide();
$("#allGUI").show();
// }).fail(function (jqxhr) {
// $("#pleaseDeploy").show();
// $("#allGUI").hide();
// });
if (node.noderedipaddress === undefined) {
// Put the default address of the machine
$.getJSON('ttsultimateGetEthAddress', (data) => {
$("#node-config-input-noderedipaddress").val(data);
});
}
if (typeof node.noderedport === "undefined") {
// Put the default port
$("#node-config-input-noderedport").val("1980");
}
if (typeof node.purgediratrestart === "undefined") {
// Put the default port
$("#node-config-input-purgediratrestart").val("leave");
}
// 22/12/2020 Hide parts of the ui
// ##########################################################
$("#node-config-input-ttsservice").change(function (e) {
if ($("#node-config-input-ttsservice").val() === "googletts") {
$("#elevenlabsForm").hide();
$("#voiceaiForm").hide();
$("#GoogleForm").show();
} else if ($("#node-config-input-ttsservice").val() === "googletranslate") {
$("#GoogleForm").hide();
$("#elevenlabsForm").hide();
$("#voiceaiForm").hide();
} else if ($("#node-config-input-ttsservice").val().includes("elevenlabs")) {
$("#GoogleForm").hide();
$("#voiceaiForm").hide();
$("#elevenlabsForm").show();
} else if ($("#node-config-input-ttsservice").val() === "voiceai") {
$("#GoogleForm").hide();
$("#elevenlabsForm").hide();
$("#voiceaiForm").show();
}
});
$("#node-config-input-ttsservice").trigger("change");
// ##########################################################
// 022/12/2020 Upload file or files
// ##########################################################
$("#googleCredentialsPath").change(function (e) {
var oFiles;
oFiles = this.files;
$.each(oFiles, function (i, file) {
var fdata = new FormData();
fdata.append("googleCreds", file);
$.ajax({
url: "ttsultimatesavegooglecredentialsfile",
type: "POST",
data: fdata, //add the FormData object to the data parameter
processData: false, //tell jquery not to process data
contentType: false,
success: function (response, status, jqxhr) {
// Refresh the combo
// The only way is to wait some time, then refresh
let myNotification = RED.notify("Your credential file has been saved in the ttsultimategooglecredentials folder (into your .node-red directory) with name googlecredentials.json\n WARNING: This file contains your credentials to access google cloud API. Please be aware of this!",
{
modal: true,
fixed: true,
type: 'info',
buttons: [
{
"text": "OK",
"class": "primary",
"click": function (e) {
myNotification.close();
}
}]
});
},
error: function (jqxhr, status, errorMessage) {
//handle error
RED.notify("Problem saving credentials: " + errorMessage + ". PLEASE, SAVE THE NODE, DEPLOY AND REOPEN THIS WINDOW.",
{
modal: false,
fixed: false,
type: 'error'
});
}
});
});
});
// ##########################################################
}
});
</script>
<script type="text/html" data-template-name="ttsultimate-config">
<div id="pleaseDeploy">
<p align="center"> THIS IS YOUR FIRST CONFIG-NODE<br/> AND I NEED TO CREATE SOME THINGS<br/> BEFORE LETTING YOU PROCEED.<br/><b>PLEASE SAVE, FULL DEPLOY <br/>AND RE-OPEN THIS WINDOW</b><br/>
TO BE ABLE TO FINISH THE CONFIGURATION SETUP<br/>
</p>
</div>
<div id="allGUI">
<div class="form-row">
<b>TTS Server configuration</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 online</u></a></span>
<br/>
<br/>
</div>
<div class="form-row">
<label for="node-config-input-name"><i class="fa fa-user"></i> Name</label>
<input type="text" id="node-config-input-name">
</div>
<div class="form-tips" style="margin-top: 8px;background-color:#ffcccc;text-align:center">If <b>YOU MUST RESTART NODE-RED</b><br/> AFTER EACH CHANGE IN THIS WINDOW!</div>
<br/>
<p><b>SONOS CONFIGURATION</b></p>
<div class="form-row">
<label for="node-config-input-noderedipaddress"><i class="fa fa-globe"></i> Node-Red IP</label>
<input type="text" id="node-config-input-noderedipaddress">
</div>
<br/>
<div class="form-row">
<label for="node-config-input-noderedport"><i class="fa fa-globe"></i> Host port</label>
<input type="text" id="node-config-input-noderedport">
</div>
<br/>
<p><b>SPEECH CONFIGURATION</b></p>
<div class="form-row">
<label for="node-config-input-ttsservice"><i class="fa fa-comments"></i> TTS Service</label>
<select id="node-config-input-ttsservice">
<option value="googletts">Google TTS</option>
<option value="googletranslate">Google free TTS</option>
<option value="elevenlabs">ElevenLabs TTS V1 (deprecated)</option>
<option value="elevenlabsv2">ElevenLabs TTS V2 Multilingual</option>
<option value="voiceai">Voice.ai TTS</option>
</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>
</div>
<div id="GoogleForm">
<div class="form-row">
<label><i class="fa fa-upload"></i> Google credentials file path</label>
<input style="width:180px" id="googleCredentialsPath" type="file">
</div>
</div>
<div id="elevenlabsForm">
<div class="form-row">
<label style="width:35%" for="node-config-input-elevenlabsKey"><i class="fa fa-user"></i> <a href="https://elevenlabs.io" target="_new">Elevenlabs</a>API key</label>
<input style="width:58%" type="text" id="node-config-input-elevenlabsKey">
</div>
</div>
<div id="voiceaiForm">
<div class="form-row">
<label style="width:35%" for="node-config-input-voiceaiKey"><i class="fa fa-user"></i> <a href="https://voice.ai" target="_new">Voice.ai</a> API key</label>
<input style="width:58%" type="text" id="node-config-input-voiceaiKey">
</div>
</div>
<div class="form-row">
<label for="node-config-input-purgediratrestart"><i class="fa fa-folder-o"></i> TTS Cache</label>
<select id="node-config-input-purgediratrestart">
<option value="purge">Purge and delete this config node's TTS cache at deploy or restart(default)</option>
<option value="leave">Leave the TTS cache folder untouched (not suggested if you have less disk space)</option>
</select>
</div>
<div class="form-row">
<label for="node-config-input-TTSRootFolderPath"><i class="fa fa-folder-o"></i> Cache root folder</label>
<input type="text" id="node-config-input-TTSRootFolderPath" placeholder="The folder must exist. Leave blank for default">
</div>
</div>
</script>
<script type="text/markdown" data-help-name="ttsultimate-config">
<p>Here you can configure your TTS engine to be used.</p>
# TTS Service node
Here you can set all parameters you need. All nodes will refer to this config node, so you need to set it only once.<br/>
IF YOU RUN NODE-RED BEHIND DOCKER OR SOMETHING ELSE, BE AWARE: <br/>
PORT USED BY THE NODE ARE 1980 (DEFAULT, HTTP FILE SERVER) AND 1400 (FOR SONOS DISCOVER). <br/>
PLEASE ALLOW MDNS AND UDP AS WELL (USED TO DISCOVER SONOS, GOOGLE CAST AND DLNA/UPNP DEVICES)
**TTS Service**<br/>
You can choose between Google (without credentials), Google TTS (require credentials and registration to google), ElevenLabs or Voice.ai TTS engines.<br/>
For Google TTS Engine, you can choose pitch and speed rate of the voice.
<br/>
<br/>
* **TTS Service using Google (without credentials)**
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.
<br/>
* **TTS Service using Google TTS**
For Google TTS Engine, you can choose pitch and speed rate of the voice.<br/>
**Google credentials file path**<br/>
Here you must select your credential file, previously downloaded from Google, [with these steps](https://www.npmjs.com/package/@google-cloud/text-to-speech):
> [Select or create a Cloud Platform project](https://console.cloud.google.com/project)<br/>
> [Enable billing for your project](https://support.google.com/cloud/answer/6293499#enable-billing)<br/>
> [Enable the Google Cloud Text-to-Speech API](https://console.cloud.google.com/flows/enableapi?apiid=texttospeech.googleapis.com)<br/>
<br/>
* **TTS Service using ElevenLabs**
Please use the V2 engine, as the V1 is deprecated and will not longer be supported. The V2 has multilingual voices and is more powerful.
You have two choiches: To register to eventlabs, or not to register. If you don't register to elevenlabs.io, you will either have access on a limited amount of voices, or no access at all.
After registration at elevenlabs.io, you can add any language to your personal list. The personal list will be then show in the node voice's list.<br/>
<br/>
* **TTS Service using Voice.ai**
Add your Voice.ai API key in the config node, deploy and restart Node-RED. The node will load your available voices and show them in the Voice dropdown.
Note: SSML is not supported by this engine.
<br/>
**Node-Red IP**<br/>
set IP of your node-red machine. Write **AUTODISCOVER** to allow the node to auto discover your IP.
**Host Port**<br/>
The players (Sonos, Google Cast, DLNA/UPnP renderers) will connect to this port to fetch the TTS audio. Default 1980. Choose a free port. Do not use 1880 or any other port already in use on your computer. The port must be reachable from the players on your network.
**TTS Cache**
<br/>
***Purge and delete the TTS cache folder at deploy or restart***<br/>
On each deploy or node-red restart, delete all tts files in the cache. This is useful not to run out of disk space, in case you've a lot of TTS speech files.
<br/>
***Leave the TTS cache folder untouched*** (suggested only if you have enough disk space)<br/>
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.
<br/>
**Cache root folder**
<br/>
Set your preferred output folder for the files downloaded by the TTS Engine.<br/>
This is useful if you wish to save the TTS cached files in a folder accessible, for example, by a third party web servers to serve an AirPlay2 speaker.<br/>
Leave this field blank for the default.<br/>
<br/>
<br/>
<p>
<a href="https://www.paypal.me/techtoday" target="_blank"><img src='https://img.shields.io/badge/Donate-PayPal-blue.svg?style=flat-square' width='30%'></a>
</p>
<p>
Configuration help is also here <a href="https://github.com/Supergiovane/node-red-contrib-tts-ultimate/blob/master/README.md">README</a><br/>
</p>
</script>