2017-07-03 7 views
9

मैं वर्तमान में कुछ शब्दों को रिकॉर्ड करने की कोशिश कर रहा हूं, जिसमें एक रिकॉर्ड दबाए जाने और दबाए जाने पर रिकॉर्ड सत्र शुरू होना चाहिए, और इसे रिलीज़ होने पर रोकें। मैं रिकॉर्डिंग और डेटा भंडारण के लिये अजगर स्क्रिप्ट बनाया ..आउटपुट ऑडियो फ़ाइल सही ढंग से नहीं बनाई गई है, या अज्ञात अवधि का समय

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 फ़ाइल अवधि अज्ञात है? क्यूं कर?

उत्तर

5

मेरे पास आपके अनुरोध का यह पहला संस्करण है। इस global के लिए क्षमा करें। मैं pynput से परिचित नहीं हूं, इसलिए मैं सिर्फ डीओसी का पालन करता हूं, pynput का सबसे सरल उदाहरण उपयोग करता हूं। तो यहां कोड जो Win7 और python3 के साथ ठीक काम करता है। स्क्रिप्ट से बाहर निकलने के लिए space को रिकॉर्ड करना, और esc को स्क्रिप्ट से बाहर निकलने के लिए।

from pynput import keyboard 
import pyaudio 
import wave 
import time 

CHUNK = 8192 
FORMAT = pyaudio.paInt16 
CHANNELS = 2 
RATE = 44100 
RECORD_SECONDS = 5 
WAVE_OUTPUT_FILENAME = "output.wav" 

record_on = False 
complete_tag = False 
frames = [] 

def callback(in_data, frame_count, time_info, status): 
    print("callback called") 
    callback_flag = pyaudio.paContinue 
    # global record_on 
    if record_on: 
     # global frames 
     frames.append(in_data) 
    if complete_tag: 
     callback_flag = pyaudio.paComplete 

    return in_data, callback_flag 

def on_press(key): 
    global record_on 
    print(record_on) 
    if key == keyboard.Key.space: 
     record_on = True 

def on_release(key): 
    global record_on 
    global complete_tag 
    record_on = False 
    complete_tag = True 
    if key == keyboard.Key.esc: 
     return False 

if __name__ == '__main__': 
    p = pyaudio.PyAudio() 
    stream = p.open(format=FORMAT, 
       channels=CHANNELS, 
       rate=RATE, 
       input=True, 
       frames_per_buffer=CHUNK, 
       stream_callback=callback) 
    with keyboard.Listener(
      on_press=on_press, 
      on_release=on_release) as listener: 
     listener.join() 
    stream.stop_stream() 
    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() 

अद्यतन:

मैं सिर्फ अपने कॉलबैक पुनर्लेखन, और यह आप के लिए अच्छा काम करेगा, लेकिन मेरे लिए नहीं।

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) 

आप कॉलबैक समझ में नहीं आता है, जब आप p.open with callback कहा जाता है, कॉलबैक जब डेटा hardware.so तर्क मेरी बजाय संस्करण while 1: time.sleep(0.1) तरह कॉलबैक में लिखना चाहिए से आते हैं बुलाया जाएगा।

इसलिए, आपकी सभी समस्या कॉलबैक की पहली कॉल के बाद है, स्ट्रीम PAabort प्राप्त करती है, फिर स्ट्रीम स्टॉप। इसलिए कॉलबैक को केवल एक बार बुलाया जाता है, इसलिए आपकी .wav फ़ाइल में मेटाडेटा है और इसमें कोई अवधि नहीं है।

और मैं अच्छी तरह से

from pynput import keyboard 
import pyaudio 
import wave 

CHUNK = 8192 
FORMAT = pyaudio.paInt16 
CHANNELS = 2 
RATE = 44100 
WAVE_OUTPUT_FILENAME = "output.wav" 

class MyListener(keyboard.Listener): 
    def __enter__(self): 
     self.p = pyaudio.PyAudio() 
     self.stream = self.p.open(format=FORMAT, 
          channels=CHANNELS, 
          rate=RATE, 
          input=True, 
          frames_per_buffer=CHUNK, 
          stream_callback = self.callback) 
     self.start() 
     return self 
    def __init__(self): 
     super(MyListener, self).__init__(on_press=self.on_press, on_release=self.on_release) 
     self.key_pressed = False 
     self.complete_tag = False 
     self.frames = [] 

    def on_press(self, key): 
     if key == keyboard.Key.space: 
      self.key_pressed = True 

    def on_release(self, key): 
     if key == keyboard.Key.space: 
      self.key_pressed = False 
      self.complete = True 
     if key == keyboard.Key.esc: 
      return False 

    def callback(self,in_data, frame_count, time_info, status): 
     callback_flag = pyaudio.paContinue 
     if self.key_pressed: 
      self.frames.append(in_data) 
     if self.complete_tag: 
      callback_flag = pyaudio.paComplete 
     return in_data, callback_flag 

    def __exit__(self, exc_type, exc_value, traceback): 
     self.stream.stop_stream() 
     self.stream.close() 
     self.p.terminate() 
     self.stop() 
     wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb') 
     wf.setnchannels(CHANNELS) 
     wf.setsampwidth(self.p.get_sample_size(FORMAT)) 
     wf.setframerate(RATE) 
     wf.writeframes(b''.join(self.frames)) 
     wf.close() 

with MyListener() as listener: 
     listener.join() 
+0

हाँ ... यह समाधान काम करता है ... लेकिन हाँ, लेकिन मैं अभी भी थोड़ा उलझन में हूं कि मेरा संस्करण क्यों काम नहीं करता है ... मुझे लगता है कि ऐसा लगता है कॉलबैक होने की समस्या को स्थानीयकृत नहीं किया जा रहा है, या केवल 'पी.ओपेन' के समय बुलाया जा रहा है लेकिन इसे कहीं और नहीं कहा जाता है ... – Smo

+0

हाँ जो काम करता है। – Smo

2

आपने अपनी सूची, frames भर नहीं ली है।

आप अपनी सूची में यह करना चाहिए:

for i in range(0, int(RATE/CHUNK * RECORD_SECONDS)): 
    data = stream.read(CHUNK) 
    frames.append(data) 

क्योंकि आप एक खाली सूची यहाँ का उपयोग कर रहे:

wf.writeframes(b''.join(frames)) 

मैं यह आपके लिए काम करता है उम्मीद है।

चीयर्स!

+0

के लिए अपने पूरे कोड को बदलने .. मैं कॉलबैक का उपयोग कर रहा है, इसलिए जब 'listener.stream.start_stream()' कहा जाता है, यह रिकॉर्ड चाहिए। – Smo

+0

@ स्ट्रीम शुरू करने से एसएसओ जादूगर रूप से निर्णय नहीं लेता कि डेटा का उपभोग कैसे करें या इसे कहां स्टोर किया जाए। क्या आपने इसे अभी तक चलाने का प्रयास किया था? संपादित करें: आपको अपना कोड दोबारा पढ़ना चाहिए। आप वास्तव में कभी भी स्ट्रीम से पढ़ रहे हैं या जानकारी को 'फ्रेम' में नहीं डाल रहे हैं, जो वास्तव में यह जवाब बता रहा है कि यह कैसे करना है। – eenblam

+0

लेकिन आपका समाधान एक निर्धारित अवधि का उपयोग कर रहा है, जिसे मैं कीबोर्ड ईवेंट के साथ करने की कोशिश कर रहा हूं। – Smo

संबंधित मुद्दे