PyQt5番外篇(2-3):沖頂大會語音答題輔助小工具之解析篇——問題採集

上期我們介紹了UI的設計,就是一個很簡單的軟體界面。這期我們講講問題採集部分。

回顧上期的

我想飛:PyQt5番外篇(2-2):沖頂大會語音答題輔助小工具之解析篇——界面搭建zhuanlan.zhihu.com圖標

請點這裡。

實現思路

一般遇到這種問題,我都會去想想有這樣的庫嗎?有哦,童鞋!PyAudio就是這貨。

通過對PyAuido的使用,我們達到錄音的目的。

先來看看效果:

https://www.zhihu.com/video/938525116724969472

如何安裝

pip install pyaudion

PyAudio為PortAudio(跨平台音頻I / O庫)提供Python綁定。 使用PyAudio,您可以輕鬆使用Python在各種平台(如GNU / Linux,Microsoft Windows和Apple Mac OS X / macOS)上播放和錄製音頻。

PyAudio的靈感來自:

  • pyPortAudio / fastaudio:用於PortAudio v18 API的Python綁定。
  • tkSnack:Tcl / Tk和Python的跨平台聲音工具包。

更多詳細的PyAudio文檔,請見:PyAudio Documentation - PyAudio 0.2.11 documentation

核心代碼解析

import pyaudionimport wavennCHUNK = 1024FORMAT = pyaudio.paInt16nCHANNELS = 1nRATE = 16000nRECORD_SECONDS = 20nWAVE_OUTPUT_FILENAME = "output.wav"nnp = pyaudio.PyAudio()nnstream = p.open(format=FORMAT,n channels=CHANNELS,n rate=RATE,n input=True,n frames_per_buffer=CHUNK)nnframes = []nfor i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):n data = stream.read(CHUNK)n frames.append(data)nnstream.stop_stream()nstream.close()np.terminate()nnwf = wave.open(WAVE_OUTPUT_FILENAME, wb)nwf.setnchannels(CHANNELS)nwf.setsampwidth(p.get_sample_size(FORMAT))nwf.setframerate(RATE)nwf.writeframes(b.join(frames))nwf.close()n

初次看到這段代碼我們應該了解到什麼呢?

是的,我們需要用到兩個模塊:pyaudio、wave

這裡簡單的介紹下wave模塊:wave模塊為WAV聲音格式提供了一個方便的界面。 它不支持壓縮/解壓縮,但支持單聲道/立體聲。

CHUNK = 1024nFORMAT = pyaudio.paInt16nCHANNELS = 1nRATE = 16000nRECORD_SECONDS = 20n

這裡一看就是一些參數設置,話說這些參數代表什麼意思呢?我等下再說。

p = pyaudio.PyAudio()n

新建一個Python到PortAudio的介面,它提供了如下的方法:

  • 初始化並終止PortAudio
  • 打開和關閉流
  • 查詢和檢查可用的PortAudio主機API
  • 查詢和檢查可用的PortAudio音頻設備

stream = p.open(format=FORMAT,n channels=CHANNELS,n rate=RATE,n input=True,n frames_per_buffer=CHUNK)n

要記錄或播放音頻,請使用pyaudio.PyAudio.open在所需設備上打開所需音頻參數的流。設置了一個pyaudio.Stream來播放或錄製音頻。具體的參數的含義如下:

  • format:採樣大小和格式。我們這裡是pyaudio.paInt16,即16位int型。
  • channels:聲道數,這裡我們設定的是單聲道。
  • rate:採樣頻率,錄音設備在一秒鐘內對聲音信號的採樣次數,採樣頻率越高聲音的還原就越真實越自然。這裡是16000。這裡是為了匹配後期語音識別的要求設置的。
  • input:指定這是否是輸入流。 默認為False。
  • frames_per_buffer:指定每個緩衝區的幀數。

frames = []nfor i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):n data = stream.read(CHUNK)n frames.append(data)n

從流中讀取樣本並不斷的存入幀這個列表中。 使用非阻塞模式時請勿調用。

stream.stop_stream()nstream.close()np.terminate()n

停止流。流停止後,不會調用寫入或讀取。調用start_stream()來恢複流。

關閉流。

終止PortAudio這個Python介面。

wf = wave.open(WAVE_OUTPUT_FILENAME, wb)n

這個比較好理解,我們要新建一個」output.wav」的音頻文件。

wf.setnchannels(CHANNELS)n

設置通道數。

wf.setsampwidth(p.get_sample_size(FORMAT))n

將示例寬度設置為n個位元組(返回之前我們指定示例格式的大小(以位元組為單位))。

wf.setframerate(RATE)n

設置幀速率。

wf.writeframes(b.join(frames))nwf.close()n

寫入音頻幀。這裡b前綴代表的就是bytes。

關閉音頻文件。

小知識

如果你對音頻方面的知識不太熟悉的話,可以參考一下這篇文章:

音頻 屬性詳解(涉及採樣率、通道數、位數、比特率、幀等)tieba.baidu.com

其它

ok,今天錄音的介紹暫時就到這裡吧,下期我們再見。如果你喜歡本篇文章,請給我

點贊

讚賞

分享給你的好友們吧!

今天完整的代碼請關注微信公眾號:學點編程吧,發送pyqt5cdly,會自動得到相應的百度網盤下載鏈接。


推薦閱讀:

python與numpy使用的一些小tips[6]
從一次CycleGAN實現聊聊TF
轉載好文章「量產型炮灰工程師」
Python學習基礎知識小結
公司里是怎麼做數據抓取的? --- 搜狗詞庫抓取&解析

TAG:PyQt | Python | 冲顶大会 |