【发布时间】:2017-12-07 00:35:22
【问题描述】:
我目前正在尝试录制一些话语,其中录制会话应在按下并按住某个键时开始,并在释放时停止。我制作了用于记录和存储数据的python脚本..
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
脚本的问题是音频文件似乎没有录制任何内容,播放时文件的持续时间未知?..
我不确定我是否理解这里可能出了什么问题..?
更新:
带有输出的新版本:
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
输出:
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.
我觉得奇怪的是
-
listener.stream.start_stream()之后流不活动 - 回调打印消息
callback只打印一次,但每次回调将数据存储到帧时都应打印,这显然只发生一次。 - output.wav 文件的持续时间未知?为什么?
【问题讨论】:
标签: python keyboard-events pyaudio