Is there any way to have pyaudio record an mp3 when a button is being held down and stop recording and export the mp3 to the date and time when the button is released?
I have Python 3.
The button I’m using is a physical button on a Raspberry Pi.
First you need to install packages:
pip install pyaudio pydub RPi.GPIO
Install FFmpeg package:
sudo apt-get install ffmpeg
Example:
import pyaudio
import wave
import time
import RPi.GPIO as GPIO
from pydub import AudioSegment
from io import BytesIO
from datetime import datetime
# Configuration
BUTTON_PIN = 17 # GPIO pin number for the button
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
RECORD_SECONDS = 0 # Not used directly in this case
# Initialize PyAudio
audio = pyaudio.PyAudio()
# GPIO setup
GPIO.setmode(GPIO.BCM)
GPIO.setup(BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
def record_audio(filename):
stream = audio.open(format=FORMAT, channels=CHANNELS,
rate=RATE, input=True, frames_per_buffer=CHUNK)
print("Recording started")
frames = []
while GPIO.input(BUTTON_PIN) == GPIO.LOW:
data = stream.read(CHUNK)
frames.append(data)
print("Recording stopped")
stream.stop_stream()
stream.close()
# Save to WAV file
wf = wave.open(filename, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(audio.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
def convert_wav_to_mp3(wav_filename, mp3_filename):
# Convert WAV to MP3 using pydub
sound = AudioSegment.from_wav(wav_filename)
sound.export(mp3_filename, format="mp3")
def main():
try:
while True:
if GPIO.input(BUTTON_PIN) == GPIO.LOW:
# Button pressed: Record audio
timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
wav_filename = f"/home/pi/recordings/{timestamp}.wav"
mp3_filename = f"/home/pi/recordings/{timestamp}.mp3"
record_audio(wav_filename)
convert_wav_to_mp3(wav_filename, mp3_filename)
print(f"Audio saved to {mp3_filename}")
# Remove WAV file if desired
# os.remove(wav_filename)
# Wait a bit to avoid multiple recordings from a single press
time.sleep(1)
else:
time.sleep(0.1) # Polling delay
except KeyboardInterrupt:
print("Exiting...")
finally:
GPIO.cleanup()
audio.terminate()
if __name__ == "__main__":
main()