Can windows play sound when I press a keyboard key? - python

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()

Related

How do you press a specific key to do something in python?

I want to know to press a specific key to do something in python and no, not the keyboard library it requires root permissions. I could just do sudo /bin/python3.7 "path of python file" but that's gonna be a pain. by the way here's my python code:
import keyboard
import pyautogui as auto
import time
auto.hotkey('alt', 'F2')
auto.write('mousepad')
time.sleep(int(1))
auto.write('do you want to start game?')
keyboard.wait('y')
from pynput.keyboard import *
import pyautogui as auto
import time
auto.hotkey('alt', 'F2')
time.sleep(int(1))
auto.write('mousepad')
time.sleep(int(1))
auto.write('do you want to start game?')
if key == Key.y:
# Stop listener
return False
def on_press(key):
doing_something_here()
with Listener(
on_press=on_press,
on_release=None) as listener:
listener.join()

The controller.type method does not work correctly inside the onpress event - Pynput

I'm building a rudimentary autocomplete for my work, and it was doing fine, until I ran into this problem.
See example
import threading
from pynput import keyboard
from pynput.keyboard import Controller
controll = Controller()
def on_press(key):
if(key == keyboard.Key.alt_l):
controll.type("RIGHT !!!")
if(key == keyboard.Key.delete or key == keyboard.Key.enter):
return False
def handleKey():
x = input('INPUT> ')
print(x)
handle = threading.Thread(target=handleKey)
handle.start()
controll.type("RIGHT !!!")
with keyboard.Listener(
on_press=on_press) as listener:
listener.join()
When you press alt, you will see the output with the wrong string;
It must be [2] RIGHT !, but it was pressed [2]ight
But note that this only happens with the method call inside the event.
Is this a known issue? Am I using it wrong? I'm really confused
I believe that only with python3 and pip3 install pynput, this will make the example work
Tested with Windows 10
I've had a similar issue when trying to press a key while listening to a key. By my experience it is next to impossible. I have even tried to use other libraries' press functions such as pyautogui and keyboard inside of the pynput on_press function.
def on_press(key):
if key = keyboard.Key.esc:
return False
else:
if len(words) > i:
# p = keyboard.KeyCode.from_char(words[i])
pyautogui.press(word[i]) // also used keyboard.press(word[i])
i += 1
else:
keyboard.Controller.press(keyboard.Key.space)
with keyboard.Listener(on_press=on_press, suppress=True) as listener:
listener.join()
I feel like since the press action and the listen action are in different threads the program has to finish one before the other. At least that is what I gathered as I also have not found a solution to this. I also tried putting the press line after the listener.join() like this:
def on_press(key):
if key != keyboard.Key.esc:
return True
with keyboard.Listener(on_press=on_press, suppress=True) as listener:
listener.join()
if len(words) > i:
# p = keyboard.KeyCode.from_char(words[i])
pyautogui.press(words[i])
i += 1
else:
keyboard.Controller.press(keyboard.Key.space)
However, this did not solve the issue either because the program finished after listening to one input and then pressing words[i] once.
Please let me know if you find something. However I may not be able to comment bc of low reputation.
I had a similar issue as well, and something like this worked for me (on Ubuntu 20.04):
from pynput import keyboard
import threading
from time import sleep
event_queue = []
event_to_callback = {
# put your own key-to-function mapping here
# keyboard.KeyCode.from_char('c') : deal_with_c
}
def process_events():
while True:
for c in event_queue:
event_to_callback[c]()
event_queue.clear()
sleep(0.2)
keyboard.Listener(on_press=lambda k: event_queue.append(k)).start()
threading.Thread(target=process_events, args=()).start()
This decouples the listener's thread from the controller's thread; any callbacks that invoke pynput.keyboard.Controller methods will now be executed on a separate thread, different from the one of the listener.

Pynput prints entered keys when Keyboard Listener finishes

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!

Stop mp3 fille which is in loop

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

How do I use Python threading to send one command at a time to a usb device?

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()

Categories