Python mp3 player can't terminate process - python

This is my code yet. I am able to play the song in background and get input from the keyboard, but I can't stop the music process in the keyboard process. Even with that flag I couldn't managed to terminate process p.
import os
import sys
from playsound import playsound
import msvcrt
import threading
from ctypes import c_buffer, windll
from random import random
from time import sleep
from sys import getfilesystemencoding
import multiprocessing
file = open('toplay.txt')
to_listen = []
n = file.readline()
def Get_Path(name):
path = os.getcwd() + '\\' + name + ".mp3"
return path
for i in range (int(n)):
name = file.readline()
if i <= int(n)-2:
name = name[:-1]
to_listen.append(Get_Path(name))
flag = 0
def Check_Keyboard():
while True:
pressedKey = msvcrt.getch()
key = bytes.decode(pressedKey)
print(key)
if key == 's':
flag = 1
if __name__ == '__main__':
for i in range(int(n)):
p = multiprocessing.Process(target=playsound(to_listen[i],
False))
p.start()
q = multiprocessing.Process(target = Check_Keyboard)
q.start()
if flag == 1:
p.terminate()

Related

image reading outputs None every other try

I was writing code to take a screenshot of a math equation then type out the answer, but it outputs "None" every 5th or so time. Was wondering if this was in some way fixable or if I should just scrap the idea. Thanks in advance :)
from pyautogui import *
import pyautogui
import time
import keyboard
import random
import win32api, win32con
import cv2
import pytesseract
from pynput.keyboard import Key, Controller
def main():
try:
while keyboard.is_pressed('q') == False:
win32api.SetCursorPos((80,60))
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,0,0)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,0,0)
time.sleep(1)
win32api.SetCursorPos((350,370))
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,0,0)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,0,0)
time.sleep(1)
while keyboard.is_pressed('q') == False:
iml = pyautogui.screenshot(region=(190,270,275,150)) #screenshot
iml.save(r'C:\Users\USER\Desktop\New folder\my_screenshot.png')
pytesseract.pytesseract.tesseract_cmd = r'C:\\Program Files\\Tesseract-OCR\\tesseract'
math = (pytesseract.image_to_string(r'C:\Users\USER\Desktop\New folder\my_screenshot.png'))
math = math.replace('+', '/')
math = math.replace('x', '*')
math = math.replace('X', '*')
if exec(math) == 'None':
math = eval(math)
else:
math = exec(math)
math = str(math)
print(math)
time.sleep(0.5)
for char in math:
keyboard.press(char)
keyboard.release(char)
except:
main()
main()

Trying to stop pygame but it can't because of interrupt

So I want it so when you click the x button on the top it stops the whole process but there is this "interrupt" error I keep getting and I tried multiple ways to stop the video, pygame or audio and none of them work. It just keeps printing in console interrupt.
import random
import psutil
import sys
from pygame.locals import *
from moviepy.editor import *
from pypresence import Presence
import time
pygame.init()
pygame.mixer.init()
pygame.display.set_caption('lofi hip hop radio - beats to relax/study to - v1.0')
def launch(movie):
clip = VideoFileClip(movie)
clip.preview()
def checkIfProcessRunning(processName):
'''
Check if there is any running process that contains the given name processName.
'''
#Iterate over the all the running process
for proc in psutil.process_iter():
try:
# Check if process name contains the given name string.
if processName.lower() in proc.name().lower():
return True
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
pass
return False;
def repeat():
running = True
clip = VideoFileClip("lofivid1.mp4")
time.sleep(5)
randomNumber = random.randint(1, 2)
print(str(randomNumber))
pygame.mixer.music.load("song" + str(randomNumber) + ".wav")
pygame.mixer.music.play()
while pygame.mixer.music.get_busy() and running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if(running):
clip.preview()
else:
pygame.quit()
exit(0)
while 1:
if checkIfProcessRunning('discord'):
client_id = 'ID CLIENT' #Put your client ID here
RPC = Presence(client_id)
RPC.connect()
print(RPC.update(state="Listening", details="Doing homework", large_image="https://static.actu.fr/uploads/2020/04/maxresdefault-960x640.jpg", small_image="https://static.actu.fr/uploads/2020/04/maxresdefault-960x640.jpg", large_text="LofiCli", start=time.time()))
else:
pass
repeat()
Every-time you click the x button you get this printed in console
Interrupt
And it does not close or change anything

Python VLC - Next track

I am writing a program in Python to run on a Raspberry Pi in order to control my Wurlitzer jukebox. The program current accepts the codes for "record selection" (A1, B1, C4, etc.), add those codes to a playlist, and executes the list. My issue is that once a song starts, I would like to be able to press a button ("Y" in the current code) to skip the currently playing song. I can't get this to work.
If I use "player.next()" I get an error: 'MediaPlayer' object has no attribute 'next'.
I tried to stop the player and restart it (thinking it would pick up the next song in the Playlist. This doesn't even stop the player.
I do not want to use subprocess if I can avoid it. I'd like to figure out a way within Python to do the skipping. How would one accomplish this?
import os, sys, csv, vlc, time, threading
from pynput.keyboard import Key, Listener
DefaultUSBPath="/media/pi"
PlayHistory="PlayHistory.csv"
#
# Declare variables
#
USBDrive = None
Action = None
Playlist = []
SelectionCount = []
Sel_char = None
#
# Find the USB Drive
#
for item in os.listdir(DefaultUSBPath):
if os.path.isdir(os.path.join(DefaultUSBPath, item)):
if USBDrive is None:
USBDrive = os.path.join(DefaultUSBPath, item)
else:
USBDrive = USBDrive + ";" + os.path.join(DefaultUSBPath, item)
if USBDrive is None:
print ("Error(0) - No USB Drive detected")
sys.exit()
elif ";" in USBDrive:
print ("Error(1) - More than one USB Drive detected.")
sys.exit()
#
# Adding to playlist - Returns directory contents and adds to playlist
#
def addplaylist(track):
list = None
if os.path.isdir(os.path.join(USBDrive, track)):
files = [f for f in os.listdir(os.path.join(USBDrive, track)) if os.path.isfile(os.path.join(USBDrive, track, f))]
for f in files:
if list is None:
list = os.path.join(USBDrive, track, f)
else:
list = list + ";" + os.path.join(USBDrive, track, f)
else:
print ("Error(2) - Selection is invalid")
if list is not None:
if ";" in list:
list = list.split(";")
else:
print ("Error(3) - Selection has no media")
return list
#
# MediaPlayer function
#
def MusicPlayer(P):
global Playlist, player
while len(Playlist) > 0:
song=Playlist.pop(0)
print("Song: ")
print(song)
player=vlc.MediaPlayer(song)
player.play()
#
# Define keyboard actions
#
def on_press(key):
global Action, Playlist, player
try:
Sel_char = int(key.char)
except:
try:
Sel_char = str(key.char)
Sel_char = Sel_char.upper()
except:
Sel_char = None
if Sel_char == "Z":
return False
elif Sel_char == "Y":
print("Skip")
#player.next() This line causes 'MediaPlayer' object has no attribute 'next'
time.sleep(1)
MusicPlayer(Playlist)
elif type(Sel_char) == str:
Action = Sel_char
elif type(Sel_char) == int:
Action = Action + str(Sel_char)
print("Action: " + Action)
Plist = addplaylist(Action)
if Plist is not None:
print("Added to playlist")
Playlist.append(Plist)
print(Plist)
MusicPlayer(Playlist)
else:
pass
#
# Read keyboard input
#
with Listener(on_press=on_press) as listener:
listener.join()
print ("")
print ("Have a nice day!")
print ("")
sys.exit()
The way you have it coded, I expect you'd have to stop it, remove the current media from the list, then re-start it.
However you may be better off running with a media_list_player, see below for a bare bones version. Note, I'm on Linux and had to hack some code to get the key input, rather than using a specific library or spend time on it, but it should give you enough to work with.
Edit
I apologise, there is a much simpler method when using a media_list_player, although if you want finer control you should use the media_list_player where you control the list's index or for full control use a media_player_new() but that's beyond the scope of this question. (I'll leave the original answer below this code, as it may be useful)
import vlc
import time
## pinched from vlc for keyboard input
import termios
import tty
import sys
mymedia = ["vp.mp3","vp1.mp3","happy.mp3","V1.mp4"]
def getch(): # getchar(), getc(stdin) #PYCHOK flake
fd = sys.stdin.fileno()
old = termios.tcgetattr(fd)
try:
tty.setraw(fd)
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old)
return ch
## end pinched code
def jukebox():
player.play_item_at_index(0)
while True:
time.sleep(0.25)
k = getch()
if k == "n": #Next
player.next()
if k == "p": #Previous
player.previous()
if k == " ": #Pause
player.pause()
if k == "q": #Quit
player.stop()
return True
player.next()
vlc_instance = vlc.Instance('--no-xlib --quiet ') # no-xlib for linux and quiet don't complain
player = vlc_instance.media_list_player_new()
Media = vlc_instance.media_list_new(mymedia)
player.set_media_list(Media)
print("Welcome to Jukebox")
print("Options - space = Play/Pause, n = Next, p = Previous, q = Quit")
print("Media",mymedia)
jukebox()
Original code
import vlc
import time
## pinched from vlc for keyboard input
import termios
import tty
import sys
def getch(): # getchar(), getc(stdin) #PYCHOK flake
fd = sys.stdin.fileno()
old = termios.tcgetattr(fd)
try:
tty.setraw(fd)
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old)
return ch
## end pinched code
vlc_instance = vlc.Instance()
player = vlc_instance.media_list_player_new()
mymedia = ["vp.mp3","vp1.mp3","happy.mp3"]
Media = vlc_instance.media_list_new(mymedia)
player.set_media_list(Media)
for index, name in enumerate(mymedia):
print("Playing:",name)
player.play_item_at_index(index)
time.sleep(1)
while player.get_state() != 6:
time.sleep(1)
k = getch()
if k == "y":
player.stop()
break

how to make a timer to a function

def choosePath():
path = ""
while path != "e" and path !="n":
print('\nWhich way do you go (n, s, e, w):\n')
t = Timer(1 * 1, timeout)
t.start()
answer = input(path)
path = path.lower()
if path =="e":
station()
elif path =="n":
estate()
elif path =="s":
building()
else:
print("\nYou return the way you came are but are soon caught by Mansons and assimilated.\n")
return path
I have received this code and want to add a timer that if answer isn't done with a certain amount of time it says gameover.
You want the Timer class in the threading module.
import threading
t = threading.Timer(<delay in secs>, <callback>, [<function args>])
t.start()
If the user has selected an option in time call t.cancel()
You need to start the timer outside of the while loop. There are also several ways to implement a timer, but this should work (I simplified it, you'll need to adjust it to your business logic)
import time
start_time = datetime.now()
max_time_allowed = 45
while path != "e" and path !="n":
#Business logic here
current_time= datetime.now()
if current_time-start_time > max_time_allowed:
return
Try creating another thread to track the time then update a global boolean:
from threading import Thread
from time import sleep
timeIsUp = False
threadKill = False
def answerTime(self):
sleep(self)
if threadKill = True:
self._is_running = False
else:
timeIsUp = True
self._is_running = False
thread = Thread(target = answerTime, args = (10)
And now you could make your main code have an additional statement in the while loop:
while path != "e" and path !="n" and timeIsUp==False:
...
if path =="e":
station()
threadKill=True
elif path =="n":
estate()
threadKill=True
elif path =="s":
building()
threadKill=True
else:
print("Time is up")

Python script to run only in a time window

how should the code look so the below script runs only between 06.30h and 8.00h??
best regards
#!/usr/bin/python
from time import strftime
import sys
import subprocess from subprocess
import Popen
import pifacedigitalio
from time import sleep
pfd = pifacedigitalio.PiFaceDigital() # creates a PiFace Digital
object testprocess = None
while strftime('%H:%M') >= '06:29':
while(True):
sleep(0.1)
if pfd.input_pins[0].value == 1 and not testprocess:
subprocess.Popen(["/bin/myscript"])
testprocess = Popen(["/bin/myscript1"])
if pfd.input_pins[0].value == 0:
if testprocess:
testprocess.kill()
testprocess = None
subprocess.Popen(["/bin/mycript"])
sleep(1)
if strftime('%H:%M') == '08:00':
sys.exit()
I would do it with something like this:
from time import strftime
import sys
while strftime('%H:%M') >= '18:00':
#Your code
if strftime('%H:%M') == '20:30':
sys.exit()
You can learn more about time module here: https://docs.python.org/2/library/time.html
just get time into a time struct and compute the number of minutes from midnight, test the time window in minutes:
lt = time.localtime()
minutes = 60*lt.tm_hour + lt.tm_min
if 60*6+30 <= minutes <= 60*8:
subprocess.Popen(["/bin/myscript"])
testprocess = Popen(["/bin/myscript1"])

Categories