How to indeterminately record user's audio, if and only if when the user press ctrl key and shut down the recording loop when the user press ctrl+c keys? So far based on some online examples build this script:
from pynput import keyboard
import time, os
import pyaudio
import wave
import sched
import sys
from playsound import playsound
CHUNK = 8192
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
WAVE_OUTPUT_FILENAME = "mic.wav"
p = pyaudio.PyAudio()
frames = []
def callback(in_data, frame_count, time_info, status):
frames.append(in_data)
return (in_data, pyaudio.paContinue)
class MyListener(keyboard.Listener):
def __init__(self):
super(MyListener, self).__init__(self.on_press, self.on_release)
self.key_pressed = None
self.wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
self.wf.setnchannels(CHANNELS)
self.wf.setsampwidth(p.get_sample_size(FORMAT))
self.wf.setframerate(RATE)
def on_press(self, key):
try:
if key.ctrl:
self.key_pressed = True
return True
except AttributeError:
sys.exit()
def on_release(self, key):
if key.ctrl:
self.key_pressed = False
return True
listener = MyListener()
listener.start()
started = False
stream = None
def recorder():
global started, p, stream, frames
while True:
try:
if listener.key_pressed and not started:
# Start the recording
try:
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK,
stream_callback = callback)
print("Stream active:", stream.is_active())
started = True
print("start Stream")
except KeyboardInterrupt:
print('\nRecording finished: ' + repr(WAVE_OUTPUT_FILENAME))
quit()
elif not listener.key_pressed and started:
print("Stop recording")
listener.wf.writeframes(b''.join(frames))
listener.wf.close()
print("You should have a wav file in the current directory")
print('-> Playing recorded sound...')
playsound(str(os.getcwd())+'/mic.wav')
os.system('python "/Users/user/rec.py"')
except KeyboardInterrupt:
print('\nRecording finished: ' + repr(WAVE_OUTPUT_FILENAME))
quit()
except AttributeError:
quit()
print ("-> Press and hold the 'ctrl' key to record your audio")
print ("-> Release the 'ctrl' key to end recording")
recorder()
The problem is that it is really inefficient, for example the computer starts heating up. The only way I found to make the program keep running and recording different audio samples was with: os.system('python "/Users/user/rec.py"'). For finishing the program I tried to either catch the exception with:
except AttributeError:
sys.exit()
or with the user input:
if key.ctrl_c:
sys.exit()
Based on pyinput docs, I tried to make effective usage of the listeners. However, for this specific scenario which is the recommended way of using those listeners?