0

I have a text-to-speech program in Python that I'm currently trying to get to work on every operating system, as before it relied on Windows Media Player. I'm trying to use PyGame to achieve this purpose, however it does not close the .mp3 file properly after using it the second time. When it loads the .mp3 file for the first time it will successfully exit it and allow the program to delete the file, but if the user opts to try again and make another text-to-speech, the .mp3 file does not exit properly and the program is unable to delete it.

import os
import time
import sys
import getpass
import pip
from contextlib import contextmanager


my_file = "Text To Speech.mp3"
username = getpass.getuser()


@contextmanager
def suppress_output():

    with open(os.devnull, "w") as devnull:
        old_stdout = sys.stdout
        sys.stdout = devnull
        try:  
            yield
        finally:
            sys.stdout = old_stdout


def check_and_remove_file():

    if os.path.isfile(my_file):
        os.remove(my_file)


def input_for_tts(message):

    try:

        tts = gTTS(text = input(message))
        tts.save('Text To Speech.mp3')
        audio = MP3(my_file)
        audio_length = audio.info.length
        pygame.mixer.init()
        pygame.mixer.music.load(my_file)
        pygame.mixer.music.play()
        time.sleep((audio_length) + 0.5)
        pygame.mixer.music.stop()
        pygame.mixer.quit()
        pygame.quit()
        check_and_remove_file()

    except KeyboardInterrupt:

        check_and_remove_file()
        print("\nGoodbye!")
        sys.exit()


with suppress_output():

    pkgs = ['mutagen', 'gTTS', 'pygame']
    for package in pkgs:
        if package not in pip.get_installed_distributions():
            pip.main(['install', package])


import pygame
from pygame.locals import *
from gtts import gTTS
from mutagen.mp3 import MP3


check_and_remove_file()


input_for_tts("Hello there " + username + ". This program is\nused to output the user's input as speech.\nPlease input something for the program to say: ")


while True:

    try:

        answer = input("\nDo you want to repeat? (Y/N) ").strip().lower()
        if answer in ["n"] or "no" in answer or "nah" in answer or "nay" in answer or "course not" in answer:
            check_and_remove_file()
            sys.exit()
        elif answer in ["y"] or "yes" in answer or "yeah" in answer or "course" in answer:
            input_for_tts("\nPlease input something for the program to say: ")
        else:
            print("\nSorry, I didn't understand that. Please try again with either Y or N.")

    except KeyboardInterrupt:

        check_and_remove_file()
        print("\nGoodbye!")
        sys.exit()
Foxes
  • 1,137
  • 3
  • 10
  • 19
  • 1
    Just some tips to improve the readability of your code: **1.** Put all the imports at the top of the program so it's easy to see the dependencies of your code. **2.** Use try-except only at the lines that reproduces the exception and not for your entire program (in this case it would be around the `input` function). **3.** Put the new line before the triple quotes (after the parenthesis) so the indention goes one level higher instead of to the lowest indention level, which can be confusing/hard to read (short demonstration [here](https://hastebin.com/uciriqizuz.http)) – Ted Klein Bergman May 27 '17 at 15:50
  • @TedKleinBergman The imports for the modules have to be after the pip install of the packages; if this is run for the first time on a new computer it will try to import the modules before installing them, which obviously won't work. The point of the triple quotes is to create an empty line in the output, making it easier to distinguish new text from the program when running it. I have, however, changed the location of the try-except to the `input` functions. – Foxes May 27 '17 at 16:07
  • My bad, then I understand why you put the imports at different places. Although, instead of having an actual new line character in the triple quotes, why not just put a `\n` at the beginning of the strings? I know that you want an answer to your question (which I don't have unfortunately) rather than suggestion to improve readability, but it might improve the chances of someone else to be able to answer it. – Ted Klein Bergman May 27 '17 at 16:16
  • @TedKleinBergman Thanks, I was unaware of `\n`. It's now been implemented into the code. – Foxes May 27 '17 at 16:50

0 Answers0