0

im using pyttsx3 for my telegram bot. i have this code.

def TTSBot(message):
    print("TTS")
    Engine.save_to_file(message.text, "Voice.mp3")
    Engine.runAndWait()
    FBot.send_audio(message.chat.id, open("Voice.mp3", "rb"), reply_to_message_id=message.id)
    print("done")

this executes when the command is called but it sends the previous command. it dosnt wait for Engine to finish it's work. how do i make it wait?

i tried using Engine.runAndWain() inside the send_audio bot it dosnt return the Voice file.

also if you know a way to not save the file and just directly input it into the commands let me know.

amiroof
  • 31
  • 3

1 Answers1

0

Please specify your operating system next time you deal with audio in case you are on linux and you simply need to install a few packages to fix this.

Now, the problem you requested is not regarding pyttsx3 but regarding FBot. I assume you are using python-telegram bot because the API looks alike. Within its docs the function bot.send_audio is async which means you must mark your function as asynchronous to await the function FBot.send_audio(). You can, of course, put the event loop inside TTSBot() but it's better to put it in their caller.

This is the complete code for reference.

import asyncio
# import other libraries

# other code

async def TTSBot(message):
    # print("TTS") (it is not advised to put simple messages like this, instead use a logger)
    Engine.save_to_file(message.text, "Voice.mp3")
    Engine.runAndWait()
    await FBot.send_audio(message.chat.id, open("Voice.mp3", "rb"), reply_to_message_id=message.id)
    #print("done") (it is not advised to put simple messages like this, instead use a logger)

def caller(): # put real function
    # other code
    asyncio.run(TTSBot(msg))
    # if you are using Python3.6 or lower, comment the previous line and uncomment the following lines
    # loop = asyncio.get_event_loop()
    # loop.run_until_complete(TTSBot(msg))
    # loop.close()
    # other code

UPDATE

Since you are using pytelegrambotapi, in its documention the audio file shall not be of type str but of type telebot.types.InputFile. Thus, you must pass it using that class.

def TTSBot(message):
    Engine.save_to_file(message.text, "Voice.mp3")
    Engine.runAndWait()
    FBot.send_audio(message.chat.id, InputFile("Voice.mp3"), reply_to_message_id=message.id)

And there's no need to modify the caller now.

Also I don't know how your caller works but I'd also like to give you a note that the function send_audio returns the message.

jett8998
  • 888
  • 2
  • 15