2017-07-03 111 views
0

現在、キーが押されている間に簡単なスクリプトを作成しようとしています。私はいくつかのデータを生成する必要があるので、スクリプトの意図は、端末に文章を促すことであり、話し手がキーを押すと、スクリプトは記録を開始し、話し手は文章を読む。文が話され、記録されているとき、キーのリリースでは、録音を停止し、したがって、音声ファイルを作成する必要があります。..pyaudioとpynput:キーを押している間の録音

これは私が現在持っているものです。

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 

私はフレームに問題があるように見えます落ち続けて、何も記録されていない。キーボードのスレッドがブロックしている可能性があるので、コールバック関数を使用して実装しました。確かに..しかし、何も記録されていないようです。 ?

答えて

0

次のようにコールバックを書き換えるだけです。

def callback(self,in_data, frame_count, time_info, status): 
    print("callback") 
    if self.key_pressed == True: 
     #stream_queue.put(in_data) 
     print("record") 
     frames.append(in_data) 
     return (in_data, pyaudio.paContinue) 

    elif self.key_pressed == False: 
     #stream_queue.put(in_data) 
     frames.append(in_data) 
     return (in_data, pyaudio.paComplete) 

    else: 
     print("not record") 
     return (in_data,pyaudio.paContinue) 

です。

1

これは少なくともWindows、Python 3.5で動作するようです。最初のコードの最大の問題点は次のとおりです。 whileループを実行します。ほとんどすべてをブロックします。 フレームがフレームリストに追加されませんでした。これでコールバックがこれを行います。

from pynput import keyboard 
import time 
import pyaudio 
import wave 
import sched 
import sys 

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): 
    frames.append(in_data) 
    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.wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb') 
     self.wf.setnchannels(CHANNELS) 
     self.wf.setsampwidth(p.get_sample_size(FORMAT)) 
     self.wf.setframerate(RATE) 
    def on_press(self, key): 
     if key.char == 'r': 
      self.key_pressed = True 
     return True 

    def on_release(self, key): 
     if key.char == 'r': 
      self.key_pressed = False 
     return True 


listener = MyListener() 
listener.start() 
started = False 
stream = None 

def recorder(): 
    global started, p, stream, frames 

    if listener.key_pressed and not started: 
     # Start the recording 
     try: 
      stream = p.open(format=FORMAT, 
          channels=CHANNELS, 
          rate=RATE, 
          input=True, 
          frames_per_buffer=CHUNK, 
          stream_callback = callback) 
      print("Stream active:", stream.is_active()) 
      started = True 
      print("start Stream") 
     except: 
      raise 

    elif not listener.key_pressed and started: 
     print("Stop recording") 
     stream.stop_stream() 
     stream.close() 
     p.terminate() 
     listener.wf.writeframes(b''.join(frames)) 
     listener.wf.close() 
     print "You should have a wav file in the current directory" 
     sys.exit() 
    # Reschedule the recorder function in 100 ms. 
    task.enter(0.1, 1, recorder,()) 


print "Press and hold the 'r' key to begin recording" 
print "Release the 'r' key to end recording" 
task = sched.scheduler(time.time, time.sleep) 
task.enter(0.1, 1, recorder,()) 
task.run() 
関連する問題