add audio and record widget
This commit is contained in:
parent
7d7f4ac472
commit
a922670413
@ -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.recording = True
|
||||
|
||||
def stop_record(self):
|
||||
if self.recording:
|
||||
self.stream.stop_stream()
|
||||
self.stream.close()
|
||||
self.wavfile.close()
|
||||
if save_file is None:
|
||||
self.replay()
|
||||
|
||||
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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
53
kivycv/recorder.py
Normal file
53
kivycv/recorder.py
Normal file
@ -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()
|
Loading…
Reference in New Issue
Block a user