大家好,我是[🌑(这是月球的背面)]。今天给大家分享一下Python用PyAudio做一个录音工具:最近一直在用录屏软件录桌面。在使用的过程中突然想到用python是不是可以作为录屏工具,也可以锻炼自己的动手能力。接下来我准备写一个关于如何用python做录屏工具的系列文章:录屏,制作视频,录制音频,合成视频,音频是基于Pyqt5做可视化窗口的,大概就以上四种部分,希望能尽快完善,上一篇我用opencv做的录屏部分,继续更新系列,使用python录制音频。应用平台windows10python3.7录音录音部分录音与录像类似,也是以数据帧的形式记录和保存。本次使用强大的第三方包PyAudio和内置的wave模块来编写代码的主体部分:pipinstallPyAudio如果出现安装失败,可以点这里下载对应的.whl文件,cp37表示python3.7环境,64表示64位操作系统。如果没有下载对应的whl包,会安装失败。下载完成后,在cmd窗口进入whl所在目录,使用pipinstallPyAudio-xx.whl完成安装。录音主要代码:frompyaudioimportPyAudio,paInt16,paContinue,paComplete#设置固定参数chunk=1024#每个buffer的帧数format_sample=paInt16#Samplingdigitschannels=2#Soundchannel:1,mono;2、doubleChannelfps=44100#Samplingfrequency#这里是录制音频的回调方法defcallback(in_data,frame_count,time_info,status):"""录制回调函数"""wf.writeframes(in_data)ifxx:#当满足某些条件时returnin_data,paContinueelse:returnin_data,paComplete#InstantiatePyAudiop=PyAudio()stream=p.open(format=format_sample,channels=channels,rate=fps,frames_per_buffer=chunk,input=True,input_device_index=None,#输入设备索引,None为默认设备stream_callback=callback#回调函数)#开始流记录s??tream.start_stream()#判断流是否活跃whilestream.is_active():time.sleep(0.1)#0.1为sensitivity#录音完成,关闭stream和实例stream.stop_stream()stream.close()p.terminate()采用stream方式,使用回调函数进行录音,需要先定义并保存音频文件,使用wave来创建一个新的音频二进制文件:importwavewf=wave.open('test.wav','wb')wf.setnchannels(channels)wf.setsampwidth(p.get_sample_size(format_sample))wf.setframerate(fps)为了后续代码的组合复用,将上面的代码包装成一个类frompyaudioimportPyAudioclassAudioRecord(PyAudio):def__init__(self,):文末附上源码。音频播放部分的播放部分的代码与录音部分的代码差别不大。核心部分:wf=wave.open('test.wav','rb')defcallback(in_data,frame_count,time_info,status):data=wf.readframes(frame_count)returndata,paContinuestream=p.open(format=p.get_format_from_width(wf.getsampwidth()),channels=wf.getnchannels(),rate=wf.getframerate(),output=True,output_device_index=output_device_index,#inputdeviceIndexstream_callback=callback#输出的回调函数)stream.start_stream()whilestream.is_active():time.sleep(0.1)目前可以正常录制和播放.wav和.mp3格式,其他类型的音频格式可以自己调用代码进行测试。GUI窗口需要的属性值代码部分考虑到GUI窗口可以更人性化的输出和输入值,写了这部分代码,包括音频时长和获取输入设备以及输出设备。#Audioduration=wf.getnframes()/wf.getframerate()#获取系统当前安装的输入输出设备dev_info=self.get_device_info_by_index(i)default_rate=int(dev_info['defaultSampleRate'])ifnotdev_info['hostApi']anddefault_rate==fpsand'mapper'notindev_info['name']:ifdev_info['maxInputChannels']:print('输入设备:',dev_info['name'])elifdev_info['maxOutputChannels']:print('输出设备:',dev_info['name'])pynputmonitorkeyboard这部分代码中也临时使用了pynputmonitorkeyboard来打断录音。可以调用上一篇文章中的键盘监听代码。defhotkey(self):"""Hotkeylistener"""withkeyboard.Listener(on_press=self.on_press)aslistener:listener.join()defon_press(self,key):try:ifkey.char=='t':#tkey,结束录音,保存音频self.flag=Trueelifkey.char=='k':#kkey,停止录音,删除文件self.flag=Trueself.kill=TrueexceptExceptionase:print(e)函数和前面类似一,不再。总结大家好,我是[🌑(这是月球的背面)]。以上就是使用PyAudio调用windows的音频设备进行录音和播放的内容。本文带你从整体上了解类的使用和类的继承。这里的用法只是冰山一角,更多知识等着我们一起探索!源代码:importwaveimporttimefrompathlibimportPathfromthreadingimportThreadfrompyaudioimportPyAudio,paInt16,paContinue,paCompletefrompynputimportkeyboard#pipinstallpynputclassAudioRecord(PyAudio):def__init__(self,channels=2):super().__init__4#(buffer1)self。.format_sample=paInt16#采样位数self.channels=channels#声道:1,单声道;2、双通道self.fps=44100#采样频率self.input_dict=Noneself.output_dict=Noneself.stream=Noneself。filename='~test.wav'self.duration=0#Audiodurationself.flag=Falseself.kill=Falsedef__call__(self,filename):"""Reloadfilename"""self.filename=filenamedefcallback_input(self,in_data,frame_count,time_info,status):"""录音回调函数"""self.wf.writeframes(in_data)ifnotself.flag:returnin_data,paContinueelse:returnin_data,paCompletedefcallback_output(self,in_data,frame_count,time_info,status):"""播放回调函数"""data=self.wf.readframes(frame_count)returndata,paContinuedefopen_stream(self,name):"""打开记录制流"""input_device_index=self.get_device_index(name,True)ifnameelseNonereturnsself.open(format=self.format_sample,channels=self.channels,rate=self.fps,frames_per_buffer=self.chunk,input=True,input_device_index=input_device_index,#输入设备索引stream_callback=self.callback_input)defaudio_record_run(self,name=None):"""音频记录"""self.wf=self.save_audio_file(self.filename)self.stream=self.open_stream(name)self.stream.start_stream()whileself.stream.is_active():time.sleep(0.1)self.wf.close()ifself.kill:Path(self.filename).unlink()self.duration=self.get_duration(self.wf)print(self.duration)self.terminate_run()defrun(self,filename=None,name=None,record=True):"""音频录制线程序"""thread_1=Thread(target=self.hotkey,daemon=True)ifrecord:#录制iffilename:self.filename=filenamethread_2=Thread(target=self.audio_record_run,args=(name,))else:#Playifnotfilename:raiseException('音频文件名无法播放,请重新输入!')thread_2=Thread(target=self.read_audio,args=(filename,name,))thread_1.start()thread_2.start()defread_audio(self,filename,name=None):"""音频播放"""output_device_index=self.get_device_index(name,False)ifnameelseNonewithwave.open(filename,'rb')asself.wf:self.duration=self.get_duration(self.wf)self.stream=self.open(format=self.get_format_from_width(self.wf.getsampwidth()),channels=self.wf.getnchannels(),rate=self.wf.getframerate(),output=True,output_device_index=output_device_index,#outputdeviceindexstream_callback=self.callback_output)self.stream.start_stream()whileself.stream.is_active():时间。睡眠(0.1)打印(self.duration)self.terminate_run()@staticmethoddefget_duration(wf):“”“获取音频持续时间”“”返回回合(wf.getnframes()/wf.getframerate(),2)defget_in_out_devices(self):"""获取系统输入输出设备"""self.input_dict={}self.output_dict={}foriinrange(self.get_device_count()):dev_info=self.get_device_info_by_index(i)default_rate=int(dev_info['defaultSampleRate'])ifnotdev_info['hostApi']anddefault_rate==self.fpsand'投影仪'notindev_info['name']:ifdev_info['maxInputChannels']:self.input_dict[dev_info['name']]=ielifdev_info['maxOutputChannels']:self.output_dict[dev_info['name']]=idefget_device_index(self,name,input_in=True):"""获取选择设置查询"""ifinput_inandself.input_dict:returnsself.input_dict.get(name,-1)elifnotinput_inandself.output_dict:returnsself.output_dict.get(name,-1)defsave_audio_file(self,filename):"""音频文件保存"""wf=wave.open(filename,'wb')wf.setnchannels(self.channels)wf.setsampwidth(self.get_sample_size(self.format_sample)))wf.setframerate(self.fps)returnwfdefterminate_run(self):"""结束束流记录或流播放"""ifself.stream:self.stream.stop_stream()self.stream.close()self.terminate()defhotkey(self):"""热键监听"""withkeyboard.Listener(on_press=self.on_press)aslistener:listener.join()defon_press(self,key):try:ifkey.char=='t':#t键,录音结束,保存音频self.flag=Trueelifkey.char=='k':#k键,停止录音,删除文件self.flag=Trueself.kill=TrueexceptExceptionase:print(e)if__name__=='__main__':audio_record=AudioRecord()audio_record.get_in_out_devices()#recordprint(audio_record.input_dict)audio_record.run('test.mp3')#playprint(audio_record.output_dict)audio_record.run('test.mp3',record=假)朋友们,我们赶快练习吧!
