Hello guys, i have been working on a text-to-speech app for an AI. I am using GTTS (Google Text To Speech). Now, when i type something in the text box, it sends that text to my python code using uplink and returns an audio-file containing the speech and it is downloaded by anvil. To play the audio-file, i have to open and play it. So, i was wondering if there is a way to play it instantly after it is returned.
Here is my Server code(Thanks David And Campopianoa)-
from io import BytesIO
import anvil.server
from gtts import gTTS
anvil.server.connect("<My Uplink Key>")
@anvil.server.callable()
def speak(audio_string):
mp3_fp = BytesIO()
tts = gTTS(audio_string, lang='en')
tts.write_to_fp(mp3_fp)
# The file saved is fine. I can play it.
tts.save("my_file.mp3")
data = open('my_file.mp3', 'rb').read()
tts_blob = anvil.BlobMedia('audio/mpeg', data, name='audio.mp3')
return tts_blob
anvil.server.wait_forever()
Here is my code-
from ._anvil_designer import Form1Template
from anvil import *
import anvil.server
class Form1(Form1Template):
def __init__(self, **properties):
# Set Form properties and Data Bindings.
self.init_components(**properties)
# Any code you write here will run when the form opens.
def text_box_1_pressed_enter(self, **event_args):
text=self.text_box_1.text
tts_blob = anvil.server.call("speak",text)
anvil.media.download(tts_blob)
"""This method is called when the user presses Enter in this text box"""
pass
So, i want to know, how i can play the downloaded file then itself…Thank You
Where exactly is the java Script function…I’m new to anvil and i don’t know where most of the stuff are… …could you please give me step-by-step instruction to make it work
for your example, it’s a little more tricky because you have the media object in python rather than in the assets… so I think -
you’ll need the url of the tts_blob object
send this to the javascript function
set the src of the <audio> tags to be the url you sent over
then play the sound with javascript…
But i’ve not done it so I’m sure
If and when you get stuck try to create an example that doesn’t require your uplink code. i.e. use the upload component or already have the audio stored in the assets. This way you can share a clone link and we can help out…
That might seem overly complex, but I’m not sure there is another way to do it. You would think it would be possible to pass the media blob directly to the javascript player in the client…
Also, you should make a background task that periodically removes the media files.
Remember most people here are just volunteers with day jobs, and will feel more inclined to help people who show they have done some research and testing, and clearly show what’s gone wrong. Your code snippet relies on others to try and guess what else you’ve done.
Please don’t take offence to what I’ve written, but if you read the links I pasted above and follow the advice, you’ll find people on here very helpful.
It can be very frustrating when things don’t work, so we do understand. Just be mindful that we are also wrestling with our own bugs and development issues.
So it is possible to get a temp URL I suppose. It seems for your purposes you only need a temp URL anyways.
Also, if you choose to use data tables to store the media, the need for a unique key I mentioned above is unnecessary. You can first create the row, get the unique ID (see the code below), and then just leave the media field empty. Then populate it when the server returns it.
# 'jane_smith' is a Row object from the 'people' table
janes_id = jane_smith.get_id()
r = app_tables.people.get_by_id(janes_id)
# r and jane_smith are equal, as they both
# point to the same row.
# (jane_smith == r)
Thank you Robert and sc459 but i don’t that wouldn’t be necessary… but i just had a crazy idea and started from square one with pyttsx3 (no specific reasons)… I used a completely different structure and IT WORKED!!!.Here is the code-
The actual need for this project was for my AI, so you might notice some changes in the code below-
(server code)
import pyttsx3
import anvil.server
anvil.server.connect("<uplink_key>")
engine = pyttsx3.init('sapi5')
voices = engine.getProperty('voices')
engine.setProperty('voice', voices[0].id)
@anvil.server.callable()
def say(text):
# This function will pronounce the string which u passed to it
engine.say(text)
engine.runAndWait()
@anvil.server.callable()
def speak():
i="hello" # This is how I actually wanted the text to be for the AI
f= "I am baymax"
return i,f;
anvil.server.wait_forever()
(client code)
from ._anvil_designer import Form1Template
from anvil import *
import anvil.server
class Form1(Form1Template):
def __init__(self, **properties):
# Set Form properties and Data Bindings.
self.init_components(**properties)
# Any code you write here will run when the form opens.
def button_1_click(self, **event_args):
w=anvil.server.call("speak")
anvil.server.call("say",w)
"""This method is called when the button is clicked"""
pass
If you were wondering that this is a whole new code and doesn’t even relate to the topic, it was because, when i was just sending a text to the speak function to speak, it would work as a python code but not with anvil;it would stop working after the first time i called the function. So with the help of David and Campopianoa, we came up with a totally different code using GTTS which sent an audio-file to anvil…and you know the rest.
So, anyway, thank you sc549,robert and david, for helping me out.
Actually, David,for a change, i didn’t use GTTS for this one; rather, i use pyttsx3. It does the text-to- speech in my server code itself engine.say(text)
Yeah. Sorry, i should have mentioned that, you don’t need to download or save any file on pyttsx3, that is only for GTTS which we were using earlier. As i got this working, i’ll just forget about GTTS…