I have some code that needs to know whether the mixer system in Pygame is initialized so it can know when to exit it, as at the moment Pygame doesn't seem to be exiting properly. 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 Pygame properly after using it the second time. When it loads the .mp3 file for the first time it will successfully exit Pygame and allow the program to delete the file, but if the user opts to try again and make another text-to-speech, it will re-initialize Pygame, write the file, open and then play the file. After the file has finished playing it will try to exit Pygame, however Pygame does not close properly and the program is unable to delete the .mp3 file as it is currently in use.
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", "no", "nah", "nay", "course not"] 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", "yes", "yeah", "course", "ye", "yea", "yh"] or "yes " in answer or "yeah " in answer or "course " in answer or "ye " in answer or "yea " in answer or "yh " 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()
To check if pygame.mixer is initialised, all you need to do is pygame.mixer.get_init() which will return the currently playing audio's data, unless it is uninitialised, in which case it will return None.
Source: https://www.pygame.org/docs/ref/mixer.html#pygame.mixer.get_init
Related
When I run my code below, the program exits after entering a link.
It looks like it is actually doing something but it doesn't print out anything. It just exits in 1-2 seconds after entering the YouTube link.
The problem only occurred after I defined the functions and put my statements in it. Before that, it worked correctly.
import sys
import getpass
import time
from pytube import YouTube
import keyboard
from termcolor import *
osusername = getpass.getuser()
print("═══════════════════════════════════")
print(" Main Menu ")
print("═══════════════════════════════════\n")
def Option1():
print("")
print("═══════════════════════════════════")
print(" YouTube Downloader ")
print("═══════════════════════════════════")
link = input("Enter the link:")
yt = YouTube(link)
print("Title: ",yt.title)
print("Number of views: ",yt.views)
print("Length of video: ",yt.length,"seconds")
print("Ratings: ",yt.rating)
print("\n")
res = input("Would you like to download this video? y/n \n")
path = 'C:\Program Files\downl'
if res == "y":
print("Downloading video...")
yt.streams.first().download(path)
else:
print("Press any button to close the program")
def Menu():
print("[1] ~ Download YouTube Videos")
def keyPressed():
while True:
try:
if keyboard.is_pressed('1'):
Option1()
except:
break
Menu()
keyPressed()
When I run your code. The Program stops and doesn't work for me too. Then I realised that the pytube installed in my system was an older version. So I simply updated the version of pytube by:
pip install --upgrade pytube
After then, when I run the code the code works pretty well.
This question already has answers here:
Python: Why should 'from <module> import *' be prohibited?
(6 answers)
Closed 5 months ago.
I am making a utility program which has multiple programs built into it but I made some changes to my program for it re-run when the user has prompted which then for some reason, I am facing the error
import * only allowed at module level
Here's my code
def main():
import os
import sys
import time
import pywhatkit as whatsapp
from speedtest import Speedtest
from tkinter import *
from tkinter import messagebox
from os import listdir
from PIL import Image
print("*"*30)
print("Utility Build v1: Starting")
print("*"*30)
time.sleep(3)
print("NOTE: Before using this program for repairing corrupted disk, please locate this utility .py file into the corrupted storage. Thanks")
time.sleep(3)
print("*"*30)
print("*"*30)
print("Commands: Choose by inputting allocated number")
print("Utility 1: Speed Test")
print("Utility 2: Whatsapp Message Automation")
time.sleep(2)
print("Please Wait...Loading")
time.sleep(4)
print("Utility 3: Disk/Removable Storage Repair(a.k.a Dr Corrupt)")
print("Utility 4: Python .py status monitor")
print("*"*30)
print("*"*30)
print("q = Quit Utility Program")
input_ = input(": ")
if input_ == "q":
exit()
if input_ == "1":
time.sleep(2)
print("*"*30)
print("Speed Test: Starting")
print("*"*30)
st = Speedtest()
Download_ = print("Your connection download speed is:", st.download())
Upload_ = print("Your connection upload speed is:", st.upload())
Download1_ = st.download()
Upload1_ = st.upload()
print("*"*30)
print("Speed Test: Finishing Up!")
print("*"*30)
answer = input("Would you like results? ")
if answer == "yes":
print("NOTE: The first 2 digits frm the left is your internet speed")
time.sleep(2)
top = Tk()
top.geometry("100x100")
messagebox.showinfo("Speed Test: Download", Download1_)
top.mainloop()
reply = input("Would like to leave Utility Build(yes) or go to home page?(no) ")
else:
reply1 = print("Would like to leave Utility Build(yes) or go to home page?(no) ")
if reply1 == "yes":
main()
else:
exit()
if input_ == "2":
whatsapp.sendwhatmsg("+61450776320", "Hi, this is a test", 0, 0)
if input_ == "3":
for filename in listdir('./'):
if filename.endswith('.png'):
try:
img = Image.open('./'+filename) # open the image file
img.verify() # verify that it is, in fact an image
except (IOError, SyntaxError) as e:
print('Bad file:', filename) # print out the names of corrupt files
"Module level" just means in a part of the script that's not in a class or function. Any names you define there go directly into the module namespace.
The error message is therefore just saying to move
def main():
import os
import sys
import time
import pywhatkit as whatsapp
from speedtest import Speedtest
from tkinter import *
from tkinter import messagebox
from os import listdir
from PIL import Image
to
import os
import sys
import time
import pywhatkit as whatsapp
from speedtest import Speedtest
from tkinter import *
from tkinter import messagebox
from os import listdir
from PIL import Image
def main():
Actually, the interpreter only really cares about the line from tkinter import *. The others are a matter of convention and readability.
CPython does optimizations on the local namespace inside a function that requires the interpreter to know the names of all local variables up-front. A star import prevents that from happening since you don't know what names will be in the imported module until you run it. The global namespace doesn't have this restriction, so you can do star imports there.
Python is a language for consenting adults. Just because something is "bad practice" or not maintainable does not make it a syntax error.
I have the following code quasi-working
from gtts import gTTS
import speech_recognition as rs
import pyaudio
import audioop
import os
import math
from os import system
import threading
from datetime import datetime
def say(text):
filename = 'speak.mp3'
language = 'en'
myobj = gTTS(text=text, lang=language, slow=False)
myobj.save(filename)
player = vlc.MediaPlayer(filename)
player.play()
def listen(x):
r=rs.Recognizer()
with rs.Microphone() as source:
audio=r.listen(source)
try:
text = r.recognize_google(audio)
process(text.lower())
except:
system('say I did not get that. Please say again.')
listen(0)
def process(text):
print(text)
# Do things here based on text
if 'what time is it' in text:
say(datetime.now().strftime("%H%M"))
return
#process("what time is it") "Seventeen oh six"
# Listen for me to say something, if I say 'what time is it' return the time
#listen(0) "Se"
If I run process(text) manually such as:
process("what time is it")
Python will speak back to me something like "1706" (Seventeen oh six)
However, if I call it from the listen() function python will start to play the file but it gets cut off and is more like "Se" and then nothing.
I've tried multiple things including using time.sleep(n) but no changes seem to make the entire file play when called through the listen(n) function.
I have a Text-To-Speech program that asks for a user input and then outputs that input as speech. It will then ask if the user wants to convert another input into speech or whether they want to exit the program. At the moment the program will only work on Windows as it is dependent on Windows Media Player to play the text-to-speech file. How could I make it so it plays the file from within Python, and, by extension, works on every operating system? If there are any other parts within the code that would prevent it from running on other Operating Systems, please tell me what they are and how I could change them as well. Thanks!
try:
import os
import time
import sys
import getpass
import pip
import subprocess
from contextlib import contextmanager
my_file = "Text To Speech.mp3"
wmp = "C:\Program Files (x86)\Windows Media Player\wmplayer.exe"
media_file = os.path.abspath(os.path.realpath(my_file))
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):
tts = gTTS(text = input(message))
tts.save('Text To Speech.mp3')
subprocess.Popen([wmp, media_file])
audio = MP3(my_file)
audio_length = audio.info.length
time.sleep((audio_length) + 2) # Waits for the audio to finish playing before killing it off.
os.system('TASKKILL /F /IM wmplayer.exe')
time.sleep(0.5) # Waits for Windows Media Player to fully close before carrying on.
with suppress_output():
pkgs = ['mutagen', 'gTTS']
for package in pkgs:
if package not in pip.get_installed_distributions():
pip.main(['install', package])
from gtts import gTTS
from mutagen.mp3 import MP3
check_and_remove_file()
input_for_tts("Hello there " + username + """. This program is
used to output the user's input as speech.
Please input something for the program to say: """)
while True:
answer = input("""
Do you want to repeat? (Y/N) """).strip().lower()
if answer in ["yes", "y"]:
input_for_tts("""
Please input something for the program to say: """)
elif answer in ["no", "n"]:
check_and_remove_file()
sys.exit()
else:
print("""
Sorry, I didn't understand that. Please try again with either Y or N.""")
except KeyboardInterrupt:
check_and_remove_file()
print("""
Goodbye!""")
sys.exit()
Instead of using Windows Media Player you can use an audio playing package. An good package that can do this is PyMedia.
So im trying to create a desktop shortcut for a terminal mp3player i made in python. I'm using Lubuntu.
My program looks like this
#!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import print_function
import os
import sys
import random
from sys import stdout
from pygame import mixer # Load the required library
class mp3Player(object):
def __init__(self):
self.mix = mixer
self.mix.init()
def play(self, filelist):
for root, mp3file in filelist:
try:
stdout.write(root + '\n')
stdout.write("Playing %s\n"%mp3file)
self.mix.music.load(os.path.join(root, mp3file))
self.mix.music.play()
while self.mix.music.get_busy():
choice = raw_input("[skip, exit, pause, shuffle]\n")
if choice == "skip":
break
elif choice == "pause":
self.mix.music.pause()
raw_input("Press enter to continiue.")
self.mix.music.unpause()
elif choice == "shuffle":
random.shuffle(filelist)
break
elif choice == "exit":
raise KeyboardInterrupt
else:
pass
except KeyboardInterrupt, e:
self.mix.music.stop()
print("User Interrupted")
sys.exit(0)
stdout.flush()
class mp3Files(object):
def __init__(self):
self.mp3player = mp3Player()
self.filelist = []
def search(self):
for root, dirs, files in os.walk(os.getcwd()):
for mp3file in files:
if mp3file.endswith(".mp3"):
self.filelist.append((root, mp3file))
self.mp3player.play(self.filelist)
def main():
mp3 = mp3Files()
mp3.search()
if __name__ == "__main__":
main()
You will need pygame in order to test it and i would recommend to execute it in your music folder because it searches the current directory recursivly for mp3 files and when it's done it plays the list.
However, this is my .desktop file.
[Desktop Entry]
Version=1.0
Name=mp3playa
Comment=Terminal mp3player
Exec=/media/jan/Volume/Musik/mp3playa
TryExec=/media/jan/Volume/Musik/mp3playa
Terminal=true
Categories=Application
Type=Application
GenericName=Simple terminal mp3player
When i double click it, it only opens a terminal without executing the script.
What am i doing wrong? oO
Thanks in advance.
Edit:
The file is executable and i executed
sudo update-desktop-database
and got a warning
Warning in file "/usr/share/applications/gnumeric.desktop": usage of
MIME type "zz-application/zz-winassoc-xls" is discouraged ("zz-
application/zz-winassoc-xls" should be replaced with
"application/vnd.ms-excel")
Finally found what i was missing.
Had to start the lxterminal first with the script as command argument.
Exec=lxterminal --command="/home/jan/Schreibtisch/mp3playa/mp3playa"