I want to stop the mp3 file immediately at key stroke by user. Here is my code:
From pygame import mixer
Import time
def music(file) :
mixer.init()
mixer.music.load(file)
while True :
try :
mixer.music.play() # duration of file 2 sec
time.sleep(3)
except KeyboardInterrupt :
mixer.music.stop()
break
Now it works, it stop the loop but after complete the playing the whole mp3. I want it to stop immediately just like an alarm. Although same file in py.exe stop the loop immediately. But not in IDLE.
To stop the music immediately, you can set up a key listener with a callback to stop the mixer.
This code worked in IDLE:
from pygame import mixer
import time
from pynput.keyboard import Key, Listener
def stopsound(evt):
global running
mixer.music.stop() # stop music
running = False # exit run loop
return False # stop key listener
def music(file) :
global running
mixer.init()
mixer.music.load(file)
running = True;
while running :
try :
mixer.music.play() # duration of file 2 sec
time.sleep(3)
except KeyboardInterrupt :
mixer.music.stop()
break
with Listener(on_press=stopsound) as listener:
music('SomeMusic.mp3')
listener.join() # wait for listener thread to finish
Related
I'm playing a game that i need to press X each 1 sec, while i press other keyboard keys, but my hands are responding to pain
first i tried to do it on javascript:
const robot = require("robotjs");
function Sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
async function Main() {
console.log("running...");
await Sleep(2500);
PressTogether();
await Main();
}
function PressTogether() {
robot.keyTap("x");
}
Main();
also on python
import pyautogui
import time
print("hey")
while True:
time.sleep(2.5)
pyautogui.press("x")
time.sleep(2.5)
pyautogui.press("x")
print("bye")
Both are pressing the X each 2.5 seconds, but both got the same problem
it freezes my keyboard, i cant press any other key
why this is happen? how to fix?
Your keyboard doesn't react since by using sleep, you suspend the whole thread. It then is not able to do anything except blocking execution.
After sleeping for 2.5 seconds you just do sending out a keyboard action (pressing x key).
Then you are suspending your thread again.
Doing so, your process feels like being frozen because you effectively block your only one main thread most of the time.
You can overcome to that behavior by introducing another thread, which is responsible for your keyboard inputs taking them from stdin.
Here is one approach for python
import pyautogui
from time import sleep
from threading import Thread
from pynput.keyboard import Key, Listener
# a custom function that blocks for a moment and simulates key press
def akp_task():
print("hey")
while True:
time.sleep(2.5)
pyautogui.press("x")
time.sleep(2.5) #this could be omitted
pyautogui.press("x") #this could be omitted
# another function that handles manual key press inputs
def mkpi_task(key):
print('\nmanual pressed: {0}'.format(key))
if key == Key.delete:
# Stop listener
return False
# create a thread for auto key press
akp_thread = Thread(target=akp_task)
# run the thread
akp_thread.start()
# create another thread for your manual key press inputs
with Listener(on_press = mkpi_task) as listener:
listener.join()
References:
threading
manual key press handling
I used this function below to keep the Python program pressing 'enter" over and over again, but when I click with the mouse, a window appears with "Python Not Responding" and then I have to close the program, so my question is; is there any way for me to catch that with Python?
Code:
def stop():
pyautogui.FAILSAFE = False
while True:
pyautogui.press('enter')
Thanks in advance!
You cannot catch your program crashing as if it were an exception. What you can do in add a delay between sending each key press:
import time
def stop():
pyautogui.FAILSAFE = False
while True:
pyautogui.press('enter')
time.sleep(0.1)
This has been keeping me up quite a bit. When using the Python pynput module with keyboard.Listener, whatever is typed whilst the keyboard is listening is printed out in Terminal after the keyboard Listener has stopped.
I've tried termios.tcflush(sys.stdout, termios.TCIOFLUSH) but it doesn't seem to clear the buffer and stop characters being printed into the Terminal window.
Any help massively appreciated! Script below -
import sys
from pynput import keyboard
import termios
global go_to_selection
def on_press(key):
global go_to_selection
if key != keyboard.Key.tab and key != keyboard.Key.shift and key != keyboard.Key.enter:
termios.tcflush(sys.stdout, termios.TCIOFLUSH)
go_to_selection = True
return False
with keyboard.Listener(on_press=on_press) as listener:
listener.join()
if go_to_selection == True:
_user_choice = input('\r\nSelection: ')
print(' Chosen: '+ str(_user_choice))
Edit:
with keyboard.Listener(on_press=on_press, suppress=True ) as listener:
listener.join()
fixes this actually, but appears to cause a 1-2 second delay before the keyboard becomes responsive again. Is this expected?
Thanks!
I'm hoping that you can look at my code and tell me how I'm not using threading correctly. I'm trying to send commands to my usb attached camera via Python's threading module. "get_live_view" tells the camera to take a low resolution image every 2 seconds. "Listener" is waiting for the character 'c' to tell "capture_image" to take a high resolution image. I tried to use threading so both functions would not simultaneously access the camera, but whenever I press 'c', I get the error message: "Could not claim the USB device... Make sure no other program or kernel module is using the device."
import os, threading
from time import sleep
from pynput.keyboard import Key, Listener
def capture_image():
os.system("gphoto2 --capture-image-and-download --no-keep")
os.system("rm capt0000.jpg")
sleep(1)
def on_press(key):
if key.char in ('c'):
print('capture')
t2 = threading.Thread(target=capture_image, args=())
t2.start(); t2.join()
def on_release(key):
if key == Key.esc:
# Stop listener
return False
def capture_preview():
os.system("gphoto2 --capture-preview")
os.system("rm capture_preview.jpg")
sleep(2)
def get_live_view():
while True:
t3=threading.Thread(target=capture_preview, args=())
t3.start(), t3.join()
t1 = threading.Thread(target=get_live_view, args=())
t1.start()
with Listener(
on_press=on_press,
on_release=on_release) as listener:
listener.join()
I found an application that allows you to do this, and I wondered if this could be done with any built-in programs (I don't mean the Caps Lock, Num Lock radio buttons, their sound can be turned on in the control panel)? This can be done on python with the code below, but my winsound.PlaySound doesn’t want to find the file and just plays the system sound of the error. This answer did not help (either through sys or creating a folder).
The code:
import winsound
import keyboard
duration = 250
q = 300
while True:
try:
if keyboard.is_pressed('q'):
winsound.PlaySound('C:\\some.wav',winsound.SND_FILENAME)
winsound.Beep(q, duration)#Since PlaySound does not want to search, you have to do it through squeak
except:
break
I discovered something similar some months ago in VB.net
Thus I suggest you to not use the winsound but the simpleaudio package.
import simpleaudio as sa
filename = 'myfile.wav'
wave_obj = sa.WaveObject.from_wave_file(filename)
play_obj = wave_obj.play()
play_obj.wait_done() # Wait until sound has finished playing
from pynput.keyboard import Listener
import simpleaudio as sa
filename = 'music.wav'
wave_obj = sa.WaveObject.from_wave_file(filename)
def on_press(key):
if key.char == 'q':
play_obj = wave_obj.play()
play_obj.wait_done()
with Listener(on_press=on_press) as listener:
listener.join()