audio_recorder.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. # -*- coding:utf-8 -*-
  2. from ssat_sdk.sat_environment import *
  3. from ssat_sdk.utils import LoggingUtil
  4. import os, sys, time
  5. import pyaudio
  6. import wave
  7. import threading
  8. import Queue
  9. READ_BUF_TIME = 0.02 #每帧长度20ms
  10. TAG = "audio_recorder"
  11. class ARecorder():
  12. def __init__(self, CHANNELS=2,RATE=44100,WIDTH=2):
  13. self.pyaudio = None
  14. self.pyStream = None
  15. self.saveWav = False
  16. self.RecordStatus = 0#0停止录制,1正在录制
  17. self.recordLock = threading.Condition()
  18. self.waveStatus = 0#0录制文件停止,1正在录制文件
  19. self.waveFile = ""
  20. self.frameQue = Queue.Queue()#存储录制的音频帧
  21. self.frameBufMax = 0 #每次录取的Buffer采集次数,也就是frameQue会存数据的次数。做到音频长度精准控制
  22. '''Record param
  23. 44.1KHZ,16bit;96khz,24bit;192Khz,32bit
  24. '''
  25. self.CHANNELS = CHANNELS
  26. self.RATE = RATE
  27. self.WIDTH = WIDTH # 采样时的字节宽度。2代表16bit
  28. self.FORMAT = pyaudio.get_format_from_width(WIDTH)
  29. # RATE = 192000
  30. # FORMAT = pyaudio.paInt32
  31. '''
  32. 查询录音设备状态
  33. True:正常,False:异常
  34. '''
  35. def getStatus(self):
  36. pa = pyaudio.PyAudio()
  37. devInfo = pa.get_default_input_device_info()
  38. print "getDeviceStatus,",devInfo
  39. if devInfo is None or len(devInfo) < 1:
  40. return False
  41. else:
  42. return True
  43. '''
  44. 录制wave文件,可以设定录制的时间,单位s。
  45. '''
  46. def recordWave(self, filePath, time, channels = 2):
  47. print "Recording wave..."
  48. self.pyaudio = pyaudio.PyAudio()
  49. self.pyStream = self.pyaudio.open(format=self.FORMAT,
  50. channels=channels,
  51. rate=self.RATE,
  52. input=True,
  53. output=False,
  54. frames_per_buffer=self.CHUNK*channels)
  55. print("* recording")
  56. frames = []
  57. for i in range(0, int(self.RATE / self.CHUNK * time)):
  58. data = self.pyStream.read(self.CHUNK)
  59. frames.append(data)
  60. print("* done")
  61. self.pyStream.stop_stream()
  62. self.pyStream.close()
  63. self.pyaudio.terminate()
  64. wf = wave.open(filePath, 'wb')
  65. wf.setnchannels(channels)
  66. wf.setsampwidth(self.WIDTH)
  67. wf.setframerate(self.RATE)
  68. wf.writeframes(b''.join(frames))
  69. wf.close()
  70. def monitor(self,timeL,saveWave = False, waveFile=None, buf_time=None):
  71. self.recordLock.acquire()
  72. if waveFile is not None:
  73. self.waveFile = waveFile
  74. else:
  75. self.waveFile = None
  76. if buf_time is None:
  77. # 每次读取的帧数。人耳最低分辨频率20Hz,所以每次抓取0.02秒的数据。方便计算短时能。
  78. self.CHUNK = int(self.RATE * READ_BUF_TIME)
  79. else:
  80. self.CHUNK = int(self.RATE * buf_time)
  81. self.frameBufMax = timeL * (self.RATE/self.CHUNK)
  82. self.frameBufDel = 1*(self.RATE/self.CHUNK) #前1秒录取的音频,需要删掉,采集的音频不准。
  83. self.pyaudio = pyaudio.PyAudio()
  84. LoggingUtil.printLog(TAG,self.pyaudio.get_default_input_device_info())
  85. self.pyStream = self.pyaudio.open(rate=self.RATE,
  86. channels=self.CHANNELS,
  87. format=self.FORMAT,
  88. input=True,
  89. frames_per_buffer=self.CHUNK,
  90. stream_callback=self.streamCallBack)
  91. self.initRecordStatus(saveWave)
  92. self.pyStream.start_stream()
  93. LoggingUtil.printLog("Record sound....")
  94. self.recordLock.wait() #等待录音结束
  95. self.recordLock.release()
  96. LoggingUtil.printLog("Record sound End")
  97. def streamCallBack(self, in_data,frame_count,time_info,status_flags):
  98. # print "streamCallBack.Thread:", threading.currentThread().getName()
  99. # print "Recording.streamCallBack:frame_count:",frame_count,";time_info:",time_info,";status_flags:",status_flags
  100. self.frameBufDel = self.frameBufDel - 1
  101. #舍弃前1秒钟的音频内容
  102. if self.frameBufDel > 0:
  103. return (None, pyaudio.paContinue)
  104. self.frameBufMax = self.frameBufMax - 1
  105. self.frameQue.put_nowait(in_data)
  106. if self.saveWav is True:
  107. self.saveWavFrame(in_data)
  108. if self.frameBufMax <= 0:
  109. self.closeRecord()
  110. return (None, pyaudio.paComplete)
  111. else:
  112. return (None, pyaudio.paContinue)
  113. def initRecordStatus(self,saveWave):
  114. self.RecordStatus = 1
  115. self.saveWav = saveWave
  116. if self.saveWav is True:
  117. self.initWavSave()
  118. def closeRecord(self):
  119. self.RecordStatus = 0
  120. self.recordLock.acquire()
  121. self.recordLock.notify()
  122. self.recordLock.release()
  123. # self.pyStream.stop_stream()
  124. self.pyStream.close()
  125. self.pyaudio.terminate()
  126. if self.saveWav is True:
  127. self.closeWavSave()
  128. def initWavSave(self):
  129. if self.waveFile is None:
  130. self.waveFile = os.path.join(getSATTmpDIR(), "monitorSound" + str(time.time()) + ".wav")
  131. print "SoundTool, initWaveSave,audioRecord:", self.waveFile
  132. try:
  133. self.wf = wave.open(self.waveFile, 'wb')
  134. self.wf.setnchannels(self.CHANNELS)
  135. self.wf.setsampwidth(self.WIDTH)
  136. self.wf.setframerate(self.RATE)
  137. self.waveStatus = 1
  138. return self.waveFile
  139. except Exception,e:
  140. LoggingUtil.printLog(TAG, "initWavSave.Audio Recorder File Open Fail!")
  141. def saveWavFrame(self, frame):
  142. # print "saveWavFrame,frame:",frame
  143. try:
  144. self.wf.writeframes(frame)
  145. except Exception,e:
  146. LoggingUtil.printLog(TAG, "saveWavFrame.Audio Recorder wave not exits!")
  147. def closeWavSave(self):
  148. try:
  149. self.wf.close()
  150. self.wf = None
  151. self.waveStatus = 0
  152. except Exception,e:
  153. LoggingUtil.printLog(TAG, "closeWavSave.Audio Recorder wave not exits!")
  154. # print "closeWavSave.Audio Recorder wave not exits!", e
  155. def getWavFile(self):
  156. if self.saveWav is True:
  157. return self.waveFile
  158. else:
  159. return None
  160. def getFrameQue(self):
  161. return self.frameQue
  162. if __name__ == "__main__":
  163. recorder = ARecorder()
  164. # recorder.recordWave("test1.wav",5)
  165. recorder.monitor(3,True)
  166. # print 11111
  167. # recorder.monitor(3,True)
  168. # print 22222
  169. # recorder.monitor(3,True)
  170. # print 33333