# -*- coding: utf-8 -*- # @Time : 18-10-16 下午12:20 # @Author : Felix Wang import pyaudio import numpy as np from scipy import fftpack import wave # 錄音 # 錄音必須安裝portaudio模塊,否則會報錯 # http://portaudio.com/docs/v19-doxydocs/compile_linux.html def recording(filename, time=0, threshold=7000): """ :param filename: 文件名 :param time: 錄音時間,如果指定時間,按時間來錄音,默認為自動識別是否結束錄音 :param threshold: 判斷錄音結束的閾值 :return: """ CHUNK = 1024 # 塊大小 FORMAT = pyaudio.paInt16 # 每次采集的位數 CHANNELS = 1 # 聲道數 RATE = 16000 # 采樣率:每秒采集數據的次數 RECORD_SECONDS = time # 錄音時間 WAVE_OUTPUT_FILENAME = filename # 文件存放位置 p = pyaudio.PyAudio() stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK) print("* 錄音中...") frames = [] if time > 0: for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)): data = stream.read(CHUNK) frames.append(data) else: stopflag = 0 stopflag2 = 0 while True: data = stream.read(CHUNK) rt_data = np.frombuffer(data, np.dtype('<i2')) # print(rt_data*10) # 傅里葉變換 fft_temp_data = fftpack.fft(rt_data, rt_data.size, overwrite_x=True) fft_data = np.abs(fft_temp_data)[0:fft_temp_data.size // 2 + 1] # 測試閾值,輸出值用來判斷閾值 # print(sum(fft_data) // len(fft_data)) # 判斷麥克風是否停止,判斷說話是否結束,# 麥克風閾值,默認7000 if sum(fft_data) // len(fft_data) > threshold: stopflag += 1 else: stopflag2 += 1 oneSecond = int(RATE / CHUNK) if stopflag2 + stopflag > oneSecond: if stopflag2 > oneSecond // 3 * 2: break else: stopflag2 = 0 stopflag = 0 frames.append(data) print("* 錄音結束") stream.stop_stream() stream.close() p.terminate() with wave.open(WAVE_OUTPUT_FILENAME, 'wb') as wf: wf.setnchannels(CHANNELS) wf.setsampwidth(p.get_sample_size(FORMAT)) wf.setframerate(RATE) wf.writeframes(b''.join(frames)) recording('ppp.mp3', time=5) # 按照時間來錄音,錄音5秒 recording('ppp.mp3') # 沒有聲音自動停止,自動停止