aplay music player with python, start/stop code - python

I am using python to write a small program that is supposed to play and stop a .wav file using aplay. I can get the file to play on the condition that button #1 is pressed, however I cannot seem to get the file to stop playing when button #2 is pressed. I have messed around with indentation and a couple other formats, but still have yet to achieve the desired result. I've included the base code that I first started with as it is the simplest. Any help would be wonderful, thank you! :)
from gpiozero import LED, Button
button1 = Button(22)
button2 = Button(17)
from time import sleep
import os
while True:
def kill():
os.system("pkill -9 aplay")
def playsong():
os.system("aplay test.wav6")
button1.when_pressed = playsong
button2.when_pressed = kill

Related

Gpiozero wait_for_release not working as it should

I'm trying to build a program that has 2 inputs connected to 2 limit switches and each of these needs to be first opened and then closed before the function respective to each button begins.
As a safety feature, I would like to block the code until the button is closed again.
After looking around online I found out that the best library is gpiozero but I can't make it work :(
The code gets stuck on the block wait_for_release() and nothing happens when releasing the button.
I don't understand why if I put btn1.wait_for_press() it goes through that but not on wait_for_release.
#btn1.wait_for_press()
#print('If I uncomment wait_for_press it comes here but get stuck on the release anyway')
Is there a way to make this work? Even another method is appreciated!
Doing wait_for_press() and then wait_for_release() doesn't work for me because I need either 1 of the 2 inputs to be pressed.
Thanks in advance, here is the code:
from gpiozero import Button
from signal import pause
btn1 = Button(12, bounce_time=0.2)
btn2= Button(20, bounce_time=0.2)
def release_btn_1():
print('Btn1 pressed')
#btn1.wait_for_press()
#print('Wait for press works')
btn1.wait_for_release()
print('Btn1 released')
#function 1
def release_btn_2():
print('Btn2 pressed')
btn2.wait_for_release()
print('Btn2 released')
#function 2
btn1.when_pressed = release_btn_1
btn2.when_pressed = release_btn_2
pause()

What is a simple solution to record audio in Python with pause, resume and no duration time?

I'm looking for a simple solution for audio recording with pause, resume and no duration time.
pyaudio, sounddevice, I can do something with them, but this is a rather low level.
The difficulty is that they require duration time for recording, that is, the recording time that must be set initially. In my case, the recording should continue until the appropriate code is called to stop.
I found code to record without duration time in sounddevice, but it's still complicated and not a library to use in other parts of the code:
https://github.com/spatialaudio/python-sounddevice/blob/master/examples/rec_unlimited.py
The easiest way to record that I was able to find is using the recorder library:
https://pypi.org/project/recorder/
Here is the code for a simple voice recorder that I managed to find:
import tkinter as tk
from tkinter import *
import recorder
window = Tk()#creating window
window.geometry('700x300')#geomtry of window
window.title('TechVidvan')#title to window
Label(window,text="Click on Start To Start Recording",font=('bold',20)).pack()#label
rec = recorder.Recorder(channels=2)
running = None
def start():
global running
if running is not None:
print('already running')
else:
running = rec.open('untitled.flac', 'wb')
running.start_recording()
Label(window,text='Recording has started').pack()
def stop():
global running
if running is not None:
running.stop_recording()
running.close()
running = None
Label(window,text='Recording has stoped').pack()
else:
print('not running')
Button(window,text='Start',bg='green',command=start,font=('bold',20)).pack()#create a button
Button(window,text='Stop',bg='green',command=stop,font=('bold',20)).pack()#create a button
window.mainloop()
But the question of pause and resume is still open.
Maybe you can advise something?
Thanks in advance!
I'd recommend using either the SimpleSound package or pyaudio
import simplesound as sa
import pyaudio as pa
for recording sound pyaudio might be a better choice, but have a play around and see what works for you <3

How to stop repeat on button press/hold - Python

I was hoping someone might have some insight on how to stop a script from continuing to repeat if a button is held (or in my case pressed longer than a second)?
Basically i've a button setup on the breadboard, and I have it coded to play an audio file when the button is pressed. This works, however if the button isn't very quickly tapped, then the audio will repeat itself until button is fully released. Also if the button is pressed and held, the audio file will just repeat indefinitely.
I've recorded a quick recording to demonstrate the issue if its helpful, here: https://streamable.com/esvoy6
I should also note that I am very new to python (coding in general actually), so its most likely something simple that I just haven't been able to find yet. I am using gpiozero for my library.
Any help or insight is greatly appreciated!
Here is what my code looks like right now:
from gpiozero import LED, Button
import vlc
import time
import sys
def sleep_minute(minutes):
sleep(minutes * 60)
# GPIO Pins of Green LED
greenLight = LED(17)
greenButton = Button(27)
# Green Button Pressed Definition
def green_btn_pressed():
print("Green Button Pressed")
greenButton.when_pressed = greenLight.on
greenButton.when_released = greenLight.on
# Executed Script
while True:
if greenButton.is_pressed:
green_btn_pressed()
time.sleep(.1)
print("Game Audio Start")
p = vlc.MediaPlayer("/home/pi/Desktop/10 Second Countdown.mp3")
p.play()
So from a brief look at it, it seems that 'time.sleep(.1)' is not doing what you are expecting. Ie. it is obviously interrupted by button presses. This is not abnormal behaviour as button presses on Ardiuno and raspPi (guessing here) would be processed as interrupts.
The script itself does not contain any prevention from double pressing or press and hold etc.
Have you put in any debug lines to see what is executing when you press the button?
I would start there and make adjustments based on what you are seeing.
I am not familiar with this gpiozero, so I can't give any insight about what it may be doing, but looking at the code and given the issue you are having, I would start with some debug lines in both functions to confirm what is happening.
Thinking about it for a minute though, could you not just change the check to 'if greenButton.is_released:'? As then you know the button has already been pressed, and the amount of time it is held in for becomes irrelevant. May also want to put in a check for if the file is already playing to stop it and start it again, or ignore and continue playing (if that is the desired behaviour).
Further suggestions:
For this section of code:
# Executed Script
while True:
if greenButton.is_pressed:
green_btn_pressed()
time.sleep(.1)
print("Game Audio Start")
p = vlc.MediaPlayer("/home/pi/Desktop/10 Second Countdown.mp3")
p.play()
You want to change this to something along these lines:
alreadyPlaying = 0
# Executed Script
while True:
if greenButton.is_pressed:
green_btn_pressed()
#Check if already playing file.
if alreadyPlaying == 1:
# Do check to see if file is still playing (google this, not sure off the top of head how to do this easiest).
# If file still playing do nothing,
#else set 'alreadyPlaying' back to '0'
break
#Check if already playing file.
if alreadyPlaying == 0:
time.sleep(.1)
print("Game Audio Start")
p = vlc.MediaPlayer("/home/pi/Desktop/10 Second Countdown.mp3")
p.play()
alreadyPlaying = 1
Hopefully you get the idea of what I am saying. Best of luck!
i think you have to write something like this in your loop:
import time, vlc
def Sound(sound):
vlc_instance = vlc.Instance()
player = vlc_instance.media_player_new()
media = vlc_instance.media_new(sound)
player.set_media(media)
player.play()
time.sleep(1.5)
duration = player.get_length() / 1000
time.sleep(duration)

Importing and using mp3s on button press

So I have coded a "copy" of the game 2048 after following a Kite youtube tutorial. I want to add a small mp3 to play anytime you click an arrow key(to move stuff around in the game) but I'm not entirely sure what i'm doing right or wrong here. How do I do this?
I've snipped the important stuff out(import music is a folder for my mp3s)
import tkinter as tk
import mp3play
import music
The two errors I'm getting are down below, the Tk in Tk() is underlined and the root in left(root...)
when i attempt to run the code like this, it highlights "import mp3play" and says there is a Syntax error. Not sure why, I have in fact installed mp3play via pip installer as well
root = Tk()
f = mp3play.load('beep.mp3'); play = lambda: f.play()
button = left(root, text = "Play", command = play)
button.pack()
root.mainloop()
in between the 2 middle sections is the def for up, down, left, and right but that would just clutter this question
Here is the stackoverflow I've referenced for it, to be honest I dont understand half of it. How can I play a sound when a tkinter button is pushed?
Take a look at this simple example using winsound which is easier to handle for small beeps.
from tkinter import *
import winsound
root = Tk()
def play():
winsound.Beep(1000, 100)
b = Button(root,text='Play',command=play)
b.pack()
root.mainloop()
winsound.Beep(1000, 100) takes two positional arguemnts, 1000 is the frequency and 100 is the duration in milliseconds.
Do let me know if any errors or doubts.
Cheers

Issues launching headless soundboard script on boot

I'm building a headless soundboard using Raspberry Pi, and as such need a way to launch the script I'm using on boot. The program was edited and tested using the default editor Pi shot up, Thonny, and everything seems to run as intended. The buttons I'm using all play the sounds I expect them to, no issues.
I went ahead and edited rc.local to run the script as soon as the Pi boots (specifically, I added sudo python /filepath/soundboard.py & above exit 0), which it does. It seems to run identically to the way it did using Thonny, but sound cuts off after about 5 seconds, even if no buttons are pressed. When I run it directly through the command line, the same issue occurs.
The code here has been compressed, as there is more than one button, but they all use the same line.
import pygame
import random
import glob
from gpiozero import Button
import time
pygame.init()
while True:
n = glob.glob('/filepath/*.wav')
btn_0 = Button(8)
btn_0.when_pressed = pygame.mixer.stop
btn_0.when.held = lambda: pygame.mixer.Sound(random.choice(n)).play()
As far as I can tell, the while loop continues to run the program, but pressing buttons does nothing. Also, since adding the loop, the code dumps a Traceback, showing the error
gpiozero.exc.GPIOPinInUse: pin 8 is already in use by <gpiozero.Button objext on pin GPIO8, pull_up=True, is_active=False>
which might have something to do with my issue? btn_0 isn't the only button to have two functions assigned to it, but the only one to throw up this error, no matter what pin I use. The error doesn't appear if I remove the loop from the code.
You create btn_0 in an infinit while loop again and again. In the second iteration btn_0 is probably the first button that is created again. But pin 8 (which should be used for the button) has been assigned to the old instance of btn_0 in the last iteration.
You should move the glob.glob statement and the button initialization outside of the While loop. If the while loop is necessary to keep you program running place it below the initialization code and iterate over nop ore pause statements (whatever works).
If pygame.init starts it own looped thread you do not need a while loop at the end at all.
I don't know anything about pygame, so the last statement is just a guess.
Example:
import pygame
import random
import glob
from gpiozero import Button
import time
pygame.init()
n = glob.glob('/filepath/*.wav')
btn_0 = Button(8)
btn_0.when_pressed = pygame.mixer.stop
btn_0.when.held = lambda: pygame.mixer.Sound(random.choice(n)).play()
while True:
nop

Categories