python 錄制系統聲音的示例
環境準備
python
- wave
- pyaudio
wave 可以通過pip直接install,在安裝pyaudio時,通過正常的pip install 直接安裝一直處於報錯階段,後來想到可以通過輪子直接安裝。
在pypi提供的安裝包中有對應的安裝包,註意,不僅僅是python2和python3的區別,python3的小版本也有點差別。可杯具的是,小主電腦裡裝的是python3.8,後來想到還有一個網站可以安裝pythonlibs,找到對應的版本後,下載下來。直接在文件所在目錄,或者在安裝中指定文件目錄中執行安裝
pip install /c/Users/root/Downloads/PyAudio-0.2.11-cp38-cp38-win_amd64.whl
代碼和運行
def audio_record(out_file, rec_time): CHUNK = 1024 FORMAT = pyaudio.paInt16 # 16bit編碼格式 CHANNELS = 1 # 單聲道 RATE = 16000 # 16000采樣頻率 p = pyaudio.PyAudio() # 創建音頻流 dev_idx = findInternalRecordingDevice(p) stream = p.open(format=FORMAT, # 音頻流wav格式 channels=CHANNELS, # 單聲道 rate=RATE, # 采樣率16000 input=True, input_device_index=dev_idx, # 指定內錄設備的id,可以不寫,使用win的默認錄音設備 frames_per_buffer=CHUNK) print("Start Recording...") frames = [] # 錄制的音頻流 # 錄制音頻數據 for i in range(0, int(RATE / CHUNK * rec_time)): # 控制錄音時間 data = stream.read(CHUNK) frames.append(data) # 錄制完成 stream.stop_stream() stream.close() p.terminate() print("Recording Done...") # 保存音頻文件 wf = wave.open(out_file, 'wb') wf.setnchannels(CHANNELS) wf.setsampwidth(p.get_sample_size(FORMAT)) wf.setframerate(RATE) wf.writeframes(b''.join(frames)) wf.close()
在使用默認錄音設備時,發現是話筒錄音,效果並不是太理想,所以就去查查能不能直接錄系統的聲音。
def findInternalRecordingDevice(p): # 要找查的設備名稱中的關鍵字 target = '立體聲混音' # 逐一查找聲音設備 for i in range(p.get_device_count()): devInfo = p.get_device_info_by_index(i) print(devInfo) if devInfo['name'].find(target) >= 0 and devInfo['hostApi'] == 0: # print('已找到內錄設備,序號是 ',i) return i print('無法找到內錄設備!') return -1
可以使用p.get_device_info_by_index()去查看系統有關聲音的設備,通過設置為立體聲混音就可以錄制系統聲音。
保存聲音
def save(fileName): # 創建pyAudio對象 p = pyaudio.PyAudio() # 打開用於保存數據的文件 wf = wave.open(fileName, 'wb') # 設置音頻參數 wf.setnchannels(CHANNELS) wf.setsampwidth(p.get_sample_size(FORMAT)) wf.setframerate(RATE) # 寫入數據 wf.writeframes(b''.join(_frames)) # 關閉文件 wf.close() # 結束pyaudio p.terminate()
保存聲音是通過上述代碼進行保存,此處的_frames是個list,是通過每錄一個chunk(數據流塊),就把這一塊的數據添加進去
然後隻需要重新創建PyAudio對象,把這個list轉為字節串保存到文件中就可以瞭
問題
上述一般可以錄到系統聲音,但在執行的時候發現,並不能。
原因是:win的輸入設備中沒有配置立體聲混音
設置步驟:
- 在win的聲音調節出,右擊打開聲音設置
- 找到管理聲音設備
- 在輸入設備處啟用立體聲混音
就此,就完成瞭錄制系統聲音的需求
註意
上述操作,可以外放,可以插入3.5mm耳機,但系統靜音和tpye-c耳機插入的時候不能錄到聲音
完整代碼
import os import pyaudio import threading import wave import time from datetime import datetime # 需要系統打開立體聲混音 # 錄音類 class Recorder(): def __init__(self, chunk=1024, channels=2, rate=44100): self.CHUNK = chunk self.FORMAT = pyaudio.paInt16 self.CHANNELS = channels self.RATE = rate self._running = True self._frames = [] # 獲取內錄設備序號,在windows操作系統上測試通過,hostAPI = 0 表明是MME設備 def findInternalRecordingDevice(self, p): # 要找查的設備名稱中的關鍵字 target = '立體聲混音' # 逐一查找聲音設備 for i in range(p.get_device_count()): devInfo = p.get_device_info_by_index(i) # print(devInfo) if devInfo['name'].find(target) >= 0 and devInfo['hostApi'] == 0: # print('已找到內錄設備,序號是 ',i) return i print('無法找到內錄設備!') return -1 # 開始錄音,開啟一個新線程進行錄音操作 def start(self): threading._start_new_thread(self.__record, ()) # 執行錄音的線程函數 def __record(self): self._running = True self._frames = [] p = pyaudio.PyAudio() # 查找內錄設備 dev_idx = self.findInternalRecordingDevice(p) if dev_idx < 0: return # 在打開輸入流時指定輸入設備 stream = p.open(input_device_index=dev_idx, format=self.FORMAT, channels=self.CHANNELS, rate=self.RATE, input=True, frames_per_buffer=self.CHUNK) # 循環讀取輸入流 while (self._running): data = stream.read(self.CHUNK) self._frames.append(data) # 停止讀取輸入流 stream.stop_stream() # 關閉輸入流 stream.close() # 結束pyaudio p.terminate() return # 停止錄音 def stop(self): self._running = False # 保存到文件 def save(self, fileName): # 創建pyAudio對象 p = pyaudio.PyAudio() # 打開用於保存數據的文件 wf = wave.open(fileName, 'wb') # 設置音頻參數 wf.setnchannels(self.CHANNELS) wf.setsampwidth(p.get_sample_size(self.FORMAT)) wf.setframerate(self.RATE) # 寫入數據 wf.writeframes(b''.join(self._frames)) # 關閉文件 wf.close() # 結束pyaudio p.terminate() if __name__ == "__main__": # 檢測當前目錄下是否有record子目錄 if not os.path.exists('record'): os.makedirs('record') print("\npython 錄音機 ....\n") print("提示:按 r 鍵並回車 開始錄音\n") i = input('請輸入操作碼:') if i == 'r': rec = Recorder() begin = time.time() print("\n開始錄音,按 s 鍵並回車 停止錄音,自動保存到 record 子目錄\n") rec.start() running = True while running: i = input("請輸入操作碼:") if i == 's': running = False print("錄音已停止") rec.stop() t = time.time() - begin print('錄音時間為%ds' % t) # 以當前時間為關鍵字保存wav文件 rec.save("record/rec_" + datetime.now().strftime("%Y-%m-%d_%H-%M-%S") + ".wav")
以上就是python 錄制系統聲音的示例的詳細內容,更多關於python 錄制系統聲音的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- Python調用百度api實現語音識別詳解
- Python+pyaudio實現音頻控制示例詳解
- 基於Pytorch實現的聲音分類實例代碼
- 如何使用 Python為你的在線會議創建一個假的攝像頭
- Python幹貨實戰之八音符醬小遊戲全過程詳解