I'm a beginner in using pyAudio library. I have a class that handle the non-blocking recording for my project. I have declared a variable for stream in init function with the data type is None. In short, I made 2 function, start_recording and stop_recording, to handle stream variable too. start_recording works well, but stop_recording function caught the error and said:
"AttributeError: 'NoneType' object has no attribute 'stop_stream'".
I know the problem is caused by the None data type that I gave in self._stream variable of init function, but I don't have any idea how to fix that error, anyone can help me? Thank you :)
p.s. here's my class I have made
class Recorder(object):
def __init__(self, channels=1, rate=44100, frames_per_buffer=1024):
self.channels = channels
self.rate = rate
self.frames_per_buffer = frames_per_buffer
self._p = pyaudio.PyAudio()
self.filewave = None
self._stream = None
def start_recording(self, filename, audio_format):
self.filewave = self.prepare_file(filename, audio_format)
self._stream = self._p.open(
format=pyaudio.paInt16,
channels=self.channels,
rate=self.rate,
input=True,
frames_per_buffer=self.frames_per_buffer,
stream_callback=self.get_callback())
self._stream.start_stream()
return self
def get_callback(self):
def callback(data, frame_count, time_info, status):
self.filewave.writeframes(data)
return data, pyaudio.paContinue
return callback
def prepare_file(self, filename, audio_format="wb"):
filewave = wave.open(filename, audio_format)
filewave.setnchannels(self.channels)
filewave.setsampwidth(self._p.get_sample_size(pyaudio.paInt16))
filewave.setframerate(self.rate)
return filewave
def stop_recording(self):
self._stream.stop_stream()
return self
def close_recording(self):
self._stream.close()
self._p.terminate()
self.filewave.close()
Also note that my code is used with ajax interface.
And my new problem is in the button click event at ajax and now I don't have any idea how to throw Recorder object on url stop at my flask, here's my code of url ajax in my routes flask, can you give me an idea? thanks before
@app.route('/start_recording', methods=['POST'])
def start_recording():
rfile = Recorder(channels=2)
rfile.start_recording('output.wav','wb')
@app.route('/stop_recording/<rfile>', methods=['POST'])
def stop_recording(rfile):
rfile.stop_recording()
In your case rfile
should be a global variable.
If you do not reference rfile
as a global variable the object is copied through and the reference to _stream is lost causing
AttributeError: 'NoneType' object has no attribute 'stop_stream
Loose the and declare rfile = Recorder(channels=2)
outside your function (like a global variable programiz.com/python-programming/…) that way between the call to def start_recording():
and def stop_recording():
you'll know that you are working on the same instance of object Recorder