Obecnie próbuję nagrać niektóre wypowiedzi, w których sesja nagrań powinna się rozpocząć po naciśnięciu i przytrzymaniu klawisza, a następnie zatrzymaniu po zwolnieniu. Zrobiłem skrypt Pythona do nagrywania i przechowywania danych ..Wyjściowy plik dźwiękowy nie został utworzony poprawnie lub ma nieznany czas trwania.
from pynput import keyboard
import time
import pyaudio
import wave
CHUNK = 8192
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output.wav"
p = pyaudio.PyAudio()
frames = []
def callback(in_data, frame_count, time_info, status):
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.stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK,
stream_callback = self.callback)
print self.stream.is_active()
def on_press(self, key):
if key == keyboard.Key.cmd_l:
self.key_pressed = True
def on_release(self, key):
if key == keyboard.Key.cmd_l:
self.key_pressed = False
def callback(self,in_data, frame_count, time_info, status):
if self.key_pressed == True:
return (in_data, pyaudio.paContinue)
elif self.key_pressed == False:
return (in_data, pyaudio.paComplete)
else:
return (in_data,pyaudio.paAbort)
listener = MyListener()
listener.start()
started = False
while True:
time.sleep(0.1)
if listener.key_pressed == True and started == False:
started = True
listener.stream.start_stream()
print "start Stream"
elif listener.key_pressed == False and started == True:
print "Something coocked"
listener.stream.stop_stream()
listener.stream.close()
p.terminate()
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
started = False
Problem ze skryptem jest plik audio nie wydaje się nagrać coś, czas trwania pliku gdy gram jest nieznany? ..
Nie jestem pewien, czy rozumiem, co tu może być nie tak ...?
Aktualizacja:
nowa wersja z wyjściem:
from pynput import keyboard
import time
import pyaudio
import StringIO
import multiprocessing
from multiprocessing import Process, Queue, queues
import wave
CHUNK = 8192
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output.wav"
p = pyaudio.PyAudio()
frames = []
stream_queue = Queue()
class MyListener(keyboard.Listener):
def __init__(self):
super(MyListener, self).__init__(on_press=self.on_press, on_release=self.on_release)
self.key_pressed = None
self.stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK,
stream_callback = self.callback)
print ("Stream active? " + str(self.stream.is_active()))
def on_press(self, key):
if key == keyboard.Key.cmd_l:
self.key_pressed = True
def on_release(self, key):
if key == keyboard.Key.cmd_l:
self.key_pressed = False
def callback(self,in_data, frame_count, time_info, status):
print "callback"
if self.key_pressed == True:
#stream_queue.put(in_data)
frames.append(data)
return (in_data, pyaudio.paContinue)
elif self.key_pressed == False:
#stream_queue.put(in_data)
frames.append(data)
return (in_data, pyaudio.paComplete)
else:
return (in_data,pyaudio.paAbort)
listener = MyListener()
listener.start()
started = False
while True:
time.sleep(0.1)
if listener.key_pressed == True and started == False:
started = True
listener.stream.start_stream()
print ("Start stream - Key is down")
elif listener.key_pressed == True and started == True:
print("stream has started and key is still down")
print("Stream is active? " + str(listener.stream.is_active()))
print("Stream is stopped? " + str(listener.stream.is_stopped()))
print("Stream is time? " + str(listener.stream.get_time()))
elif listener.key_pressed == False and started == True:
print("Key has been released")
listener.stream.stop_stream()
listener.stream.close()
print("stream has been closed")
p.terminate()
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
started = False
wyjściowa:
python File2.py
Stream active? True
callback
Start stream - Key is down
stream has started and key is still down
Stream is active? False
Stream is stopped? False
Stream is time? 134638.797766
stream has started and key is still down
Stream is active? False
Stream is stopped? False
Stream is time? 134638.902259
stream has started and key is still down
Stream is active? False
Stream is stopped? False
Stream is time? 134639.006739
stream has started and key is still down
Stream is active? False
Stream is stopped? False
Stream is time? 134639.111282
stream has started and key is still down
Stream is active? False
Stream is stopped? False
Stream is time? 134639.215573
stream has started and key is still down
Stream is active? False
Stream is stopped? False
Stream is time? 134639.320448
stream has started and key is still down
Stream is active? False
Stream is stopped? False
Stream is time? 134639.424682
stream has started and key is still down
Stream is active? False
Stream is stopped? False
Stream is time? 134639.528631
stream has started and key is still down
Stream is active? False
Stream is stopped? False
Stream is time? 134639.633699
stream has started and key is still down
Stream is active? False
Stream is stopped? False
Stream is time? 134639.738129
stream has started and key is still down
Stream is active? False
Stream is stopped? False
Stream is time? 134639.842747
Key has been released
stream has been closed
^CTraceback (most recent call last):
File "File2.py", line 67, in <module>
time.sleep(0.1)
KeyboardInterrupt
MacBook-Pro:~$ play output.wav
output.wav:
File Size: 44
Encoding: Signed PCM
Channels: 2 @ 16-bit
Samplerate: 44100Hz
Replaygain: off
Duration: unknown
In:0.00% 00:00:00.00 [00:00:00.00] Out:0 [ | ] Clip:0
Done.
Rzeczy, które wydaje się dziwne dla mnie jest
- Strumień nie jest aktywny po wydrukowaniu komunikatu o oddzwanianiu odsyłającego o numerze tylko drukowanie jednokrotne, ale powinien być drukowany za każdym razem, gdy wywołanie zwrotne przechowuje dane w ramkach, które tylko zdarzają się raz.
- czas trwania pliku output.wav jest nieznany? czemu?
Tak ... to rozwiązanie działa ... ale tak, ale nadal jestem nieco zdezorientowany, dlaczego moja wersja nie działa ... Wydaje mi się, że mam zlokalizował problem polegający na tym, że wywołanie zwrotne nie jest wywoływane lub jest wywoływane tylko raz, gdy 'p.open', ale nie jest wywoływane nigdzie indziej ... – Smo
tak, działało. – Smo