python使用pyaudio錄音和格式轉(zhuǎn)化方式
使用pyaudio錄音和格式轉(zhuǎn)化
環(huán)境
pip3 install pyaudio pip3 install wave pip3 install numpy?
- linux 21.04
- python 3.7
代碼(Record類)
#!/bin/python3 # 標(biāo)識(shí)引用的python版本 import pyaudio import wave import sys import os import numpy as np """ 首先集成一下錄音功能和格式轉(zhuǎn)換功能 """ class Record(): ? ? """ ? ? 錄音的類 ? ? CHUNK = 1024 ? ? FORMAT = pyaudio.paInt16 ? ? ? CHANNELS = 1 ?聲道 ? ? RATE = 16000 ?頻率 ? ? RECORD_SECONDS = 5 ?錄音時(shí)間 ?單位=> s ? ? WAVE_OUTPUT_FILENAME = os.getcwd() + "/python/output1.wav" ? 錄音文件 ? ? """ ? ? def __init__(self,WAVE_OUTPUT_FILENAME,CHUNK=1024, ? ? FORMAT=pyaudio.paInt16,CHANNELS=1,RECORD_SECONDS=5, ? ? Input=True,RATE=16000,PCMName="out.pcm",DataType=np.int16): ? ? ? ? self.CHUNK = CHUNK ? ? ? ? self.FORMAT = FORMAT ? ? ? ? self.CHANNELS = CHANNELS ? ? ? ? self.RECORD_SECONDS = RECORD_SECONDS ? ? ? ? self.WAVE_OUTPUT_FILENAME = WAVE_OUTPUT_FILENAME ? ? ? ? self.Input = Input ? ? ? ? self.RATE = RATE ? ? ? ? self.PCMName = PCMName ? ? ? ? self.DataType = DataType ? ? def recording(self): ? ? ? ? """ ? ? ? ? 這句代碼 會(huì)屏蔽一些不必要的報(bào)錯(cuò) ? ? ? ? os.close(sys.stderr.fileno()) ? ? ? ? """ ? ? ? ? #隱藏一些報(bào)錯(cuò),這些不影響程序的運(yùn)行 ? ? ? ? os.close(sys.stderr.fileno()) ? ? ? ? print("開始錄音") ? ? ? ? p = pyaudio.PyAudio() ? ? ? ? stream = p.open(format=self.FORMAT, ? ? ? ? ? ? ? ? channels=self.CHANNELS, ? ? ? ? ? ? ? ? rate=self.RATE, ? ? ? ? ? ? ? ? input=self.Input,#默認(rèn)為True ? ? ? ? ? ? ? ? frames_per_buffer=self.CHUNK) ? ? ? ? frames = [] ? ? ? ? for i in range(0, int(self.RATE / self.CHUNK * self.RECORD_SECONDS)): ? ? ? ? ? ? data = stream.read(self.CHUNK) ? ? ? ? ? ? frames.append(data) ? ? ? ? print("done") ? ? ? ? # 關(guān)閉流 ? ? ? ? stream.stop_stream() ? ? ? ? stream.close() ? ? ? ? p.terminate() ? ? ? ? wf = wave.open(self.WAVE_OUTPUT_FILENAME, 'wb') ? ? ? ? wf.setnchannels(self.CHANNELS) ? ? ? ? wf.setsampwidth(p.get_sample_size(self.FORMAT)) ? ? ? ? wf.setframerate(self.RATE) ? ? ? ? wf.writeframes(b''.join(frames)) ? ? ? ? wf.close() ? ? def wav2pcm(self): ? ? ? ? """ ? ? ? ? 音頻文件wav格式 轉(zhuǎn) pcm格式 ? ? ? ? """ ? ? ? ? f = open(self.WAVE_OUTPUT_FILENAME, "rb") ? ? ? ? f.seek(0) ? ? ? ? f.read(1024) ? ? ? ? data = np.fromfile(f, dtype=self.DataType) ? ? ? ? # 獲取 分割后的 數(shù)組 ? ? ? ? filePath = ?str(self.WAVE_OUTPUT_FILENAME).split('/') ? ? ? ? path = '' ? ? ? ? # 拼接路徑 取出最后一位 [0,-1) ? ? ? ? for item in filePath[:-1]: ? ? ? ? ? ? path += item +'/' ? ? ? ? path += self.PCMName? ? ? ? ? # print("PCM Path =>",path) ? ? ? ? data.tofile(path) ? ? ? ? print("結(jié)束") ? ? ? ? # 可以返回一個(gè)元組; 也可以把它封成數(shù)組返回 ? ? ? ? return (self.WAVE_OUTPUT_FILENAME,path) ? ? def run(self): ? ? ? ? self.recording() ? ? ? ? wavpath,path = self.wav2pcm() ? ? ? ? # print("wave =>",wavpath,"\n","path =>",path) # 這個(gè)就不寫入那個(gè)類里了, 這樣方便調(diào)用 不需要再初始化類了 # 可直接copy到使用的類中或者文件里 def pcm2wav(pcmfile,wavfile,channels=1,rate=16000): ? ? with open(pcmfile,'rb') as fp: ? ? ? ? pcmdata = fp.read() ? ? with wave.open(wavfile, 'wb') as wav: ? ? ? ? wav.setnchannels(channels) ? ? ? ? wav.setsampwidth(16 // 8) ? ? ? ? wav.setframerate(rate) ? ? ? ? ? ? # 寫入 ? ? ? ? wav.writeframes(pcmdata) # 測試 if __name__ == "__main__": ? ? wavepath = os.getcwd() + "/python/output1.wav" ? ? ? dev = Record(wavepath) ? ? # dev.run() ? ? pcmfile = os.getcwd() + '/python/demo.pcm' ? ? wavfile = os.getcwd() + '/python/demo.wav' ? ? pcm2wav(pcmfile,wavfile)?
pyaudio播放聲音不清晰問題
在樹莓派上使用pyaudio播放pcm文件的時(shí)候,發(fā)現(xiàn)明顯的不清晰,感覺有輕微的斷斷續(xù)續(xù),而使用aplay播放則非常清晰
測試文件:https://sis-sample-audio.obs.cn-north-1.myhuaweicloud.com/16k16bit.pcm
>>> import pyaudio >>> p = pyaudio.PyAudio() >>> stream = p.open(format=pyaudio.paInt16, channels=1, output=True) >>> with open("16k16bit.pcm", "rb") as f: ... ? ? stream.write(f.read())
>>> aplay -f cd -c 1 -r 16000 16k16bit.pcm
最后發(fā)現(xiàn)是由于緩沖區(qū)的幀數(shù)過少導(dǎo)致播放不流暢,默認(rèn)pyaudio緩沖區(qū)的幀數(shù)為1024??梢酝ㄟ^提高frames_per_buffer參數(shù)值來解決。
>>> import pyaudio >>> p = pyaudio.PyAudio() >>> stream = p.open(format=pyaudio.paInt16, channels=1, rate=16000, frames_per_buffer=4096, output=True) >>> with open("16k16bit.pcm", "rb") as f: ... ? ? stream.write(f.read())
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python創(chuàng)建二維數(shù)組實(shí)例(關(guān)于list的一個(gè)小坑)
下面小編就為大家?guī)硪黄狿ython創(chuàng)建二維數(shù)組實(shí)例(關(guān)于list的一個(gè)小坑)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-11-11python利用dir函數(shù)查看類中所有成員函數(shù)示例代碼
這篇文章主要給大家介紹了關(guān)于python如何利用dir函數(shù)查看類中所有成員函數(shù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)下吧。2017-09-09windows10安裝python依賴報(bào)錯(cuò)can‘t?create?or?remove?files?in?i
這篇文章主要介紹了windows10安裝python依賴報(bào)錯(cuò)can‘t?create?or?remove?files?in?install?directory問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助2023-09-09Python字符串的15個(gè)基本操作(小結(jié))
這篇文章主要介紹了Python字符串的15個(gè)基本操作,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02