diff --git a/kivycv/audio.py b/kivycv/audio.py index 487e5db..d2b375e 100644 --- a/kivycv/audio.py +++ b/kivycv/audio.py @@ -16,6 +16,7 @@ class Audio(AppLogger, pyaudio.PyAudio): self.chunk = 1024 self.devices = [ self.get_device_info_by_index(i) \ for i in range(self.get_device_count()) ] + self.recording = False def get_input_device(self): return [ d for d in self.devices if d.maxInputChannels > 0 ] @@ -27,24 +28,16 @@ class Audio(AppLogger, pyaudio.PyAudio): x = tempfile.mkstemp(suffix='.wav') os.close(x[0]) self.temp_filename = x[1] + return self.temp_filename def record_cb(self, in_data, frame_count, time_info, status): - bdata = pickle.dumps(in_data) - self.info('frame_count=%s, time_info=%s, status=%s, bytes count=%s', \ - frame_count, time_info, status, len(bdata)) - self.rec_frames += frame_count - self.current_ts = time.time() self.wavfile.writeframesraw(in_data) - if self.running: + if self.recording: return (None, pyaudio.paContinue) - return (None, pyaudio.paComplete) def replay_cb(self, in_data, frame_count, time_info, status): data = self.wavfile.readframes(frame_count) - bdata = pickle.dumps(data) - self.info('frame_count=%s, data length in bytes=%s', \ - frame_count, len(bdata)) if not data: return (None, pyaudio.paComplete) @@ -57,35 +50,42 @@ class Audio(AppLogger, pyaudio.PyAudio): print(x) return dev_cnt - 1 - def record(self, save_file=None, stop_cond_func=None): - filename = save_file - if filename is None: - self.tmpfile() - filename = self.temp_filename - - self.wavfile = wave.open(filename, 'wb') - self.wavfile.setnchannels(2) - self.wavfile.setsampwidth(2) - self.wavfile.setframerate(44100.00) - self.stream = self.open(format=pyaudio.paInt16, + def start_record(self, + savefile=None, channels=2, - rate=44100, + rate=44100 + ): + if savefile is None: + savefile = self.tmpfile() + self.save_file = savefile + self.wavfile = wave.open(self.save_file, 'wb') + self.wavfile.setnchannels(channels) + self.wavfile.setsampwidth(2) + self.wavfile.setframerate(rate) + self.stream = self.open(format=pyaudio.paInt16, + channels=channels, + rate=rate, input=True, frames_per_buffer=self.chunk, stream_callback=self.record_cb) self.stream.start_stream() - self.running = True - self.rec_frames = 0 - self.start_ts = self.current_ts = time.time() - while self.stream.is_active(): - if stop_cond_func and stop_cond_func(): - self.running = False - time.sleep(0.05) - self.stream.stop_stream() - self.stream.close() - self.wavfile.close() - if save_file is None: - self.replay() + self.recording = True + + def stop_record(self): + if self.recording: + self.stream.stop_stream() + self.stream.close() + self.wavfile.close() + + def record(self, stop_cb, + savefile=None, + channels=2, + rate=44100, + ): + self.start_record(savefile=savefile, channels=channels,rate=rate) + while not stop_cb(): + time.sleep(0.1) + self.stop_record() def replay(self, play_file=None): idx = self.get_output_index() @@ -118,9 +118,12 @@ class Audio(AppLogger, pyaudio.PyAudio): if __name__ == '__main__': import sys + t_begin = time.time() def stop_func(audio): - if audio.current_ts - audio.start_ts >= 10: - audio.running = False + t = time.time() + if t - t_begin >= 10: + return True + return False create_logger('audio', levelname='debug') a = Audio() @@ -135,4 +138,4 @@ if __name__ == '__main__': if len(sys.argv) >= 2: sf = sys.argv[1] f = partial(stop_func, a) - a.record(sf, stop_cond_func=f) + a.record(f, savefile=sf) diff --git a/kivycv/audiorecorder.py b/kivycv/audiorecorder.py index 89c5e9a..dd8873c 100644 --- a/kivycv/audiorecorder.py +++ b/kivycv/audiorecorder.py @@ -3,14 +3,14 @@ import tempfile import pyaudio import wave from kivy.event import EventDispatcher -from kivy.properties import NumericProperty +from kivy.properties import NumericProperty, StringProperty, ObjectProperty from kivyblocks.baseWidget import HBox -from kviycv.micphone import Micphone +from kivycv.micphone import Micphone class AudioRecorder(EventDispatcher): fs = NumericProperty(None) filename = StringProperty(None) - voice_src = OjbectProperty(None) + voice_src = ObjectProperty(None) def __init__(self, **kw): super(AudioRecorder, self).__init__(**kw) self.saving = False diff --git a/kivycv/camerawithmic.py b/kivycv/camerawithmic.py index 7b01505..79517e3 100644 --- a/kivycv/camerawithmic.py +++ b/kivycv/camerawithmic.py @@ -6,7 +6,7 @@ from kivy.uix.camera import Camera from kivy.properties import NumericProperty from kivy.event import EventDispatcher -from .android_rotation import * +from kivyblocks.android_rotation import * if kivy.platform in [ 'win', 'linux', 'macosx' ]: from PIL import ImageGrab diff --git a/kivycv/recorder.py b/kivycv/recorder.py new file mode 100644 index 0000000..ac30805 --- /dev/null +++ b/kivycv/recorder.py @@ -0,0 +1,53 @@ +import pyaudio +from kivy.uix.label import Label +from kivy.properties import NumericProperty +from kivyblocks.baseWidget import HBox, VBox +import os +import sys +import time +try: + from .audio import Audio +except: + from audio import Audio + +class Recorder(VBox): + rate = NumericProperty(44100) + channel = NumericProperty(2) + def __init__(self, **kw): + super().__init__(**kw) + self.audio = Audio() + self.register_event_type('on_recorded') + + def on_recorded(self, record_file): + print('on_recorded:', record_file) + + def on_touch_down(self, touch): + if self.collide_point(*touch.pos): + self.audio.start_record(channels=self.channel, + rate=self.rate) + return False + return super().on_touch_down(touch) + + def on_touch_up(self, touch): + if self.audio.recording: + self.audio.stop_record() + self.dispatch('on_recorded', self.audio.save_file) + + return super().on_touch_up(touch) + +if __name__ == '__main__': + from kivy.app import App + class TestApp(App): + def build(self): + x = Recorder() + self.recorder = x + x.bind(on_recorded=self.play_audio) + return x + + def play_audio(self, o, f): + print('play file', f) + self.recorder.audio.replay(f) + print('play finished') + # os.remove(f) + + TestApp().run()