#!/usr/bin/env bash | |
# By Psycho | |
# Shell script to handle different TTS and online / offline connectivity | |
# This bash script can be set as a custom TTS for snips but also called directly from your skills | |
# a great way to give more than one personality to your assistant | |
# Original script: https://gist.github.com/Psychokiller1888/cf10af3220b5cd6d9c92c709c6af92c2 | |
####### COMMON ####### | |
#------------------------------------ | |
# Set your cache path | |
cache="/home/pi/snipsSuperTTS/cache" | |
#------------------------------------ | |
# - Install mpg123 | |
# - The cache path is created by the script itself at first run! If you already have the cache directories, make sure to set its owner to "_snips" => sudo chown _snips /home/pi/snipsSuperTTS/cache | |
# - Edit /etc/snips.toml | |
# - Set "customtts" as snips-tts provider | |
# - Add as customtts: command = ["/home/pi/snipsSuperTTS/snipsSuperTTS.sh", "%%OUTPUT_FILE%%", "google", "%%LANG%%", "US", "Wavenet-C", "FEMALE", "%%TEXT%%", "22050"] | |
# Change "US" to another language country code, "GB" per exemple for a british voice | |
# You can customize the "Wavenet-C" to another voice of your choice. https://cloud.google.com/text-to-speech/docs/voices / https://docs.aws.amazon.com/polly/latest/dg/voicelist.html | |
# Offline voices possibilities are: picotts or mycroft | |
# Fit "FEMALE" to the voice gender you want. Note this is linked to google voices | |
# You can change the sample rate, the last argument, to your needs | |
# Restart snips: systemctl restart snips-* | |
# If you want a total customized experience, you can easily enable both google and amazon and use a different one depending on what you want. Don't be shy, there's no limit | |
# Note that not all parameters do something depending on the voice you choose. Those are marked with "--" in the provided examples | |
####### MycroftAI - Mimic ####### | |
# https://github.com/MycroftAI/mimic | |
# This one is pretty long to install, but hey, the quality compared to pico is worth it! | |
# Set the following option to True to use Mycroft instead of pico. Don't forget to set the path too | |
# | |
# Example: command = ["/home/pi/snipsSuperTTS/snipsSuperTTS.sh", "%%OUTPUT_FILE%%", "mycroft", "%%LANG%%", "--", "slt_hts", "--", "%%TEXT%%", "22050"] | |
# | |
# Available voices: aew ahw aup awb axb bdl clb eey fem gka jmk ksp ljm rms rxr slt slt_hts | |
# Or you can use an external voice on http. | |
# | |
# sudo apt-get install gcc make pkg-config automake libtool libasound2-dev | |
# git clone https://github.com/MycroftAI/mimic.git | |
# cd mimic | |
# ./dependencies.sh --prefix="/usr/local" | |
# ./autogen.sh | |
# ./configure --prefix="/usr/local" | |
# make | |
# sudo /sbin/ldconfig | |
# make check | |
useMycroft=false | |
mycroftPath="/home/pi/mimic" | |
####### GOOGLE ####### | |
# Install Google SDK: https://cloud.google.com/text-to-speech/docs/quickstart-protocol | |
# Follow point 6. to initialize the sdk after creating your service account | |
# Get your api key from the console https://console.developers.google.com | |
# Uncomment the following and set it accordingly: | |
# | |
#googleWavenetAPIKey="" | |
# | |
# Example: command = ["/home/pi/snipsSuperTTS/snipsSuperTTS.sh", "%%OUTPUT_FILE%%", "google", "%%LANG%%", "US", "Wavenet-C", "FEMALE", "%%TEXT%%", "22050"] | |
###### AMAZON ####### | |
# Install Amazon sdk | |
# curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip" | |
# unzip awscli-bundle.zip | |
# ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws | |
# Uncomment the following lines and set them accordingly: | |
# | |
#export AWS_ACCESS_KEY_ID="" | |
#export AWS_SECRET_ACCESS_KEY="" | |
#export AWS_DEFAULT_REGION="eu-central-1" | |
#awscli='/usr/local/bin/aws' | |
# | |
# command = ["/home/pi/snipsSuperTTS/snipsSuperTTS.sh", "%%OUTPUT_FILE%%", "amazon", "%%LANG%%", "US", "Joanna", "--", "%%TEXT%%", "22050"] | |
# | |
#################################################################################################### | |
outfile="$1" | |
service="$2" | |
lang="$3" | |
country="$4" | |
voice="$5" | |
gender="$6" | |
text="$7" | |
sampleRate="$8" | |
if [ "$service" = "mycroft" ] || [ "$service" = "picotts" ]; then | |
status="offline" | |
else | |
echo -e "GET http://google.com HTTP/1.0\n\n" | nc google.com 80 > /dev/null 2>&1 | |
if [ $? -eq 0 ]; then | |
status="online" | |
else | |
status="offline" | |
fi | |
# Alternative for some people having problem pinging google.com. Comment the above and uncomment the following | |
#wget -q --tries=1 --timeout=1 --spider http://google.com | |
#if [[ $? -eq 0 ]]; then | |
# status="online" | |
#else | |
# status="offline" | |
#fi | |
fi | |
function picotts() { | |
case "$lang" in | |
*en*) | |
lang="en-US";; | |
*de*) | |
lang="de-DE";; | |
*es*) | |
lang="es-ES";; | |
*fr*) | |
lang="fr-FR";; | |
*it*) | |
lang="it-IT";; | |
*) | |
lang="en-US";; | |
esac | |
text=$(sed 's/<[^>]*>//g' <<< "$text") | |
pico2wave -w "$outfile" -l "$lang" "$text" | |
} | |
function mycroft() { | |
text=$(sed 's/<[^>]*>//g' <<< "$text") | |
."$mycroftPath/mimic" -t "$text" -o "$outfile" -voice "$mycroftPath""/voices/cmu_us_""$voice"".flitevox" | |
} | |
if [ "$service" = "google" ]; then | |
cache="$cache/google/" | |
mkdir -p "$cache" | |
text=${text//\'/\\\'} | |
languageCode="$lang"-"$country" | |
googleVoice="$languageCode"-"$voice" | |
md5string="$text"_"$googleVoice"_"$sampleRate"_"$lang" | |
hash="$(echo -n "$md5string" | md5sum | sed 's/ .*$//')" | |
cachefile="$cache""$hash".wav | |
downloadFile="/tmp/""$hash" | |
if [[ -f "$cachefile" ]]; then | |
cp "$cachefile" "$outfile" | |
else | |
if [ "$status" != "online" ]; then | |
if [[ "$useMycroft" = true ]]; then | |
mycroft | |
else | |
picotts | |
fi | |
else | |
if [ "$text" != *"<speak>"* ]; then | |
text="<speak>""$text""</speak>" | |
fi | |
curl -H "Content-Type: application/json; charset=utf-8" \ | |
--data "{ | |
'input':{ | |
'ssml':'$text' | |
}, | |
'voice':{ | |
'languageCode':'$languageCode', | |
'name':'$googleVoice', | |
'ssmlGender':'$gender' | |
}, | |
'audioConfig':{ | |
'audioEncoding':'MP3', | |
'sampleRateHertz':'$sampleRate' | |
} | |
}" "https://texttospeech.googleapis.com/v1/text:synthesize?key="$googleWavenetAPIKey > "$downloadFile" | |
sed -i 's/audioContent//' "$downloadFile" && \ | |
tr -d '\n ":{}' < "$downloadFile" > "$downloadFile".tmp && \ | |
base64 "$downloadFile".tmp --decode > "$downloadFile".mp3 | |
mpg123 --quiet --wav "$cachefile" "$downloadFile".mp3 | |
rm "$downloadFile" && \ | |
rm "$downloadFile".tmp && \ | |
rm "$downloadFile".mp3 | |
cp "$cachefile" "$outfile" | |
fi | |
fi | |
elif [ "$service" = "amazon" ]; then | |
cache="$cache/amazon/" | |
mkdir -p "$cache" | |
amazonVoice=$voice | |
md5string="$text""_""$amazonVoice"_"$sampleRate"_"$lang" | |
hash="$(echo -n "$md5string" | md5sum | sed 's/ .*$//')" | |
cachefile="$cache""$hash".mp3 | |
if [ -f "$cachefile" ]; then | |
mpg123 -q -w $outfile $cachefile | |
else | |
if [ "$status" != "online" ]; then | |
if [[ "$useMycroft" = true ]]; then | |
mycroft | |
else | |
picotts | |
fi | |
else | |
if [ "$text" != *"<speak>"* ];then | |
text="<speak>""$text""</speak>" | |
fi | |
$awscli polly synthesize-speech \ | |
--output-format mp3 \ | |
--voice-id "$voice" \ | |
--sample-rate "$sampleRate" \ | |
--text-type ssml \ | |
--text "$text" \ | |
"$cachefile" | |
mpg123 -q -w $outfile $cachefile | |
fi | |
fi | |
elif [ "$service" = "picotts" ]; then | |
picotts | |
elif [ "$service" = "mycroft" ]; then | |
mycroft | |
else | |
if [[ "$useMycroft" = true ]]; then | |
mycroft | |
else | |
picotts | |
fi | |
fi |
This comment has been minimized.
This comment has been minimized.
An exemple, for both google or amazon Edit snips.toml:
Restart snips: |
This comment has been minimized.
This comment has been minimized.
Update to enable ssml on Google, and to remove any ssml tags when using pico |
This comment has been minimized.
This comment has been minimized.
Added Mycroft Mimic TTS support with install instructions. Note that the install is really long, but definitly worth it for an offline TTS to replace the dusty picotts |
This comment has been minimized.
This comment has been minimized.
In your second comment - is that format correct: Shouldn't there be no commas? i.e.
|
This comment has been minimized.
This comment has been minimized.
No, it's an array, so it takes commas |
This comment has been minimized.
This comment has been minimized.
It seems that if |
This comment has been minimized.
This comment has been minimized.
By Toxip: https://forum.snips.ai/t/snipssupertts-on-script-to-rule-them-all/747/16?u=psycho
|
This comment has been minimized.
This comment has been minimized.
seems that you have to install snips-asr-google even if you want to use amazon, otherwise it stays offline.
|
This comment has been minimized.
This comment has been minimized.
Hi Psycho, and happy new year.
If I want to use only mimic (not google or amazon), do i need to change on sh script:
and i don't understand how i can:
in the toml file, i need to add:
Is it correct ? |
This comment has been minimized.
This comment has been minimized.
Re the errors, try to reach microft, those errors are explained on their github About the command, well, if you want to use "microft" why do you specify "google"? command = ["/home/pi/snipsSuperTTS/snipsSuperTTS.sh", "%%OUTPUT_FILE%%", "mycroft", "%%LANG%%", "FR", "slt", "FEMALE", "%%TEXT%%", "22050"] Note that lang and gender params won't do anything if you force mycroft use |
This comment has been minimized.
This comment has been minimized.
Thanks Psycho. Sorry i made a mistake. I don't modify the toml, i ask you what do i need to do after make the compilation. But, i dont make the modifications in the toml due to 9 errors... I will keep a look on their github. |
This comment has been minimized.
This comment has been minimized.
Just one question, to avoid a mistake, where do i need to post this request on mimic github ? |
This comment has been minimized.
This comment has been minimized.
Hurmf, i did again the installation and it is okay. I have 9 pass with green colors, oh yes ! But i have modified my toml like this: [snips-tts] After restarting snips service, when i try to say using jeedom+snips plugin some sentences, i heard the original snips voice... Why i don't heard mycroft voice ? EDIT : i have installed snips-tts on my satellite. Do i need to make the installation again on the snips server ? |
This comment has been minimized.
This comment has been minimized.
Definitively, i don't understand what i'm doing wrong... I have configured polly AWS (key_id, secret_access_key and default_region="eu-west-3" after done the installation using the command lines provided in the sh script. I add this line in the snips.toml server (not satellite !) https://i.imgur.com/k1t9RgP.png I have installed google sdk, configuring API, copy the json file in the script directory, auth etc ... I add this line (comment the previous) again... no voice ! I don't understand what i'm doing wrong... When i'm removing customtts snips voice works again... |
This comment has been minimized.
This comment has been minimized.
Hi,
after line 132 so it shows in the logs. If it is offline, it will switch back to picoTTS. if you have an error, it will fail. I had a permission problem where the user _snips needed to have access to the script.
|
This comment has been minimized.
This comment has been minimized.
You shouldn't install it on satellites, Snips sends the audio from main to satellites. So uninstall your tts service on the satellites and make sur this is running on the main |
This comment has been minimized.
This comment has been minimized.
@danito You are mixing TTS and ASR. What does google-asr to do with this? I'm using the script daily using both amazon and google and the online check works, I don't know what problems you encounter |
This comment has been minimized.
This comment has been minimized.
Thank you !
If i try: i have: If i try: i have the same error but with but in this case, i heard mimic in english ! not in french... customtts = { command = ["/home/boss/snipsSuperTTS/snipsSuperTTS.sh", "%%OUTPUT_FILE%%", "mycroft", "%%LANG%%", "FR", "slt", "FEMALE", "%%TEXT%%", "22050"] } mimic executable is in /home/boss/snipsSuperTTS/mimic directory so to launch it i've tried /home/boss/snipsSuperTTS/mimic/mimic/mimic (in case of...) lol ! Again... no working. |
This comment has been minimized.
This comment has been minimized.
Hi Psychokiller1888, You are apparently checking for snips-asr-google to be running, otherwise you set the status to offline... He commented it out (I commented it out, too) and then the check works also without snips-asr-google installed (Actually I just removed the '-google' and check for snips-asr now...) The other thing he mentioned saved my day. The Snips Platform (snips-tts) needs access rights to the cache folder and apparently it does not have these out of the box since it is not running under the 'pi' account (where the cache folder lives). Thanks for the great work! And thank you @danito, too! Your comment was extremely helpful! Regards from Berlin! |
This comment has been minimized.
This comment has been minimized.
Oh, that's still the old script, I did not update it on the gist, my bad, sorry, fixing it immediately |
This comment has been minimized.
This comment has been minimized.
Hi, |
This comment has been minimized.
This comment has been minimized.
I hate gist.... Why don't they add notifications?? @github ffs! Goods ideas, doing it! |
This comment has been minimized.
This comment has been minimized.
hmmm thisn is doing my head in, I have the script working but can not get the google side working, I have no idea what I'm doing wring |
This comment has been minimized.
This comment has been minimized.
Thanks for this great script. I've only tried it with Mycroft for now, but I did have to add the executable in line 125: from: to: |
This comment has been minimized.
This comment has been minimized.
@Psychokiller1888
|
This comment has been minimized.
This comment has been minimized.
The |
This comment has been minimized.
This comment has been minimized.
To speed up Google TTS, just create an API key in Google cloud console and add "?key=XXX" to the Google URL while removing the Authorization-Header. Way faster than generating access tokens at each call. |
This comment has been minimized.
This comment has been minimized.
@hokascha Thx! I updated to use the api key! |
This comment has been minimized.
This comment has been minimized.
Thank you also! Will add it. I have a few others coming also, such as IBM |
This comment has been minimized.
This comment has been minimized.
How would you go about changing Google TTS mp3 to LINEAR16?
When I do this the cache file is created but playback is a short 'glitch/chirp' sound. Google TTS API states that a .wav header is included when requesting LINEAR16.
|
This comment has been minimized.
This comment has been minimized.
Is the audio file ok somewhat? I mean, if you open it with audacity per exemple, and change the rates and all, is it a normal sound file? |
This comment has been minimized.
This comment has been minimized.
@Psychokiller1888 Thanks for the reply. This worked for me for LINEAR16 with aplay.
|
This comment has been minimized.
This comment has been minimized.
Hey I try to setup snips super tts with Google. And it works if I execute the script from the command line with Google but not if I set it up via /etc/snips.toml. With Mycroft it works perfectly. And I don't have any clue what to do to get it work. Any suggestions? |
This comment has been minimized.
This comment has been minimized.
did you edit the script to put your credentials? Check /var/log/syslog for errors returned also |
This comment has been minimized.
This comment has been minimized.
Yes I edited it and put my credentials in the scripts. And if I execute the script from the command line it works with Google so the API key is correct. But if I try to call the script from snips it doesn't work with Google but it works with Mycroft so the path and everything should be also correct. |
This comment has been minimized.
This comment has been minimized.
So it's most prolly a premission issue. Check your syslog to see if it fails accessing the cache directory |
This comment has been minimized.
This comment has been minimized.
I thought I already changed the owner of the cache directory but it seems like I forgot about that... Now it works perfectly! Thanks for the fast help |
This comment has been minimized.
This comment has been minimized.
hi psycho, the first time i installed this a few weeks ago everything worked fine. Now that i've started with a fresh copy of stretch and snips ive tried setting this up again but have the following error when trying to install mimic
been that way for three days now. i also cant ping ftp.csx.cam.ac.uk so assuming the site is down ?? cheers |
This comment has been minimized.
This comment has been minimized.
FYI. and that seemed to be a good alternative so far.
|
This comment has been minimized.
This comment has been minimized.
@Psychokiller1888 |
This comment has been minimized.
This comment has been minimized.
Hi, I have problems to get this running. I installed the AWS cli bundle successfully. I added this to snips.toml after uncommenting customtts provider:
I created an additional IAM account in AWS, giving it the Polly access profile. The keys I got there I put here:
When I now give a command to Snips, everything works fine but I hear no voice and sam watch says:
Of course there is no voice when it is asked to play 0kb ... the question is how I find out why the file did not get created? |
This comment has been minimized.
This comment has been minimized.
I connected to the AWS console and can see that the key was used today...so it must have connected to AWS successfully. I also ran aws configure and used polly through aws cli which created me a mp3 successfully. But with Snips still no success. |
This comment has been minimized.
This comment has been minimized.
Okay, I found the problem in the syslog. The girls name is Vicki, not Vicky. She doesn't like being called Vicky... :) |
This comment has been minimized.
This comment has been minimized.
I think it more a permission problem. You can check the syslog when it tries to answer |
This comment has been minimized.
This comment has been minimized.
Yeah that way I found it I spelled the name of the voice girl wrong. Now it's working :) Installed mimic first, then realised it can't speak german :/ |
This comment has been minimized.
This comment has been minimized.
Yeah, it's sad mimic only speaks english |
This comment has been minimized.
This comment has been minimized.
Anyways, thanks for your work! Polly is quite nice. However a local solution that speaks german would be great. |
This comment has been minimized.
This comment has been minimized.
Hi @Psychokiller1888, |
This comment has been minimized.
This comment has been minimized.
Hi @Psychokiller1888, Unfortunately, I can`t get it running. Here is what I did so far: Any clues are very welcome. Thank you very much! |
This comment has been minimized.
This comment has been minimized.
Hi! As the error states, there's a syntax error on line 104 of you shell script |
This comment has been minimized.
This comment has been minimized.
Thank you for the quick reply! I thought so, but I did not change anything in that line. Lines 104-107 are: |
This comment has been minimized.
This comment has been minimized.
@Pittermaennchen check the lines before 103. Might have lost a } ? |
This comment has been minimized.
This comment has been minimized.
hm. I can't find the source of the error. :( The lines before are: outfile="$1" if [ "$service" = "mycroft" ] || [ "$service" = "picotts" ]; then |
This comment has been minimized.
This contains a connectivity check, and in case of being offline, falls back to cached file if available and if not goes picotts