最近新系統上線,刷緩存刷個不停,准備利用語音完成此操作,解放雙手,不知道能不能實現,先一點點來。。
實現步驟拆分:
1、語音識別(百度語音識別api)
2、識別后操作前台實現刷新緩存
3、。。。
想要調用百度的語音識別功能,需要如下步驟
1、需要先注冊百度雲的賬號
2、在控制台中創建個應用,獲取到API Key 和 Secret Key
3、根據文檔中心手冊,使用(speech/len方式)JSON格式POST上傳本地文件到 http://vop.baidu.com/server_api 或 https://vop.baidu.com/server_api
4、根據返回查看報錯或成功解析后文字
1)第一步不說
2)第二步完成如圖
3)json 參數
JSON方式上傳
語音數據和其他參數通過標准 JSON 格式串行化 POST 上傳, JSON 里包括的參數:
字段名 | 可需 | 描述 |
---|---|---|
format | 必填 | 語音文件的格式,pcm 或者 wav 或者 amr。不區分大小寫。推薦pcm文件 |
rate | 必填 | 采樣率,16000,固定值 |
channel | 必填 | 聲道數,僅支持單聲道,請填寫固定值 1 |
cuid | 必填 | 用戶唯一標識,用來區分用戶,計算UV值。建議填寫能區分用戶的機器 MAC 地址或 IMEI 碼,長度為60字符以內。 |
token | 必填 | 開放平台獲取到的開發者[access_token]獲取 Access Token "access_token") |
dev_pid | 選填 | 不填寫lan參數生效,都不填寫,默認1537(普通話 輸入法模型),dev_pid參數見本節開頭的表格 |
lan | 選填,廢棄參數 | 歷史兼容參數,請使用dev_pid。如果dev_pid填寫,該參數會被覆蓋。語種選擇,輸入法模型,默認中文(zh)。 中文=zh、粵語=ct、英文=en,不區分大小寫。 |
url | 選填 | 可下載的語音下載地址,與callback連一起使用,確保百度服務器可以訪問。 |
callback | 選填 | 用戶服務器的識別結果回調地址,確保百度服務器可以訪問 |
speech | 選填 | 本地語音文件的的二進制語音數據 ,需要進行base64 編碼。與len參數連一起使用。 |
len | 選填 | 本地語音文件的的字節數,單位字節 |
樣例:
{
"format":"pcm",
"rate":16000,
"dev_pid":1536,
"channel":1,
"token":xxx,
"cuid":"baidu_workshop",
"len":4096,
"speech":"xxx", // xxx為 base64(FILE_CONTENT)
}
注意點:formate 為 語音文件格式
格式支持:pcm(不壓縮)、wav(不壓縮,pcm編碼)、amr(壓縮格式);固定16k 采樣率;
cuid:可以隨意填,但是必須要有
speech為base64編碼格式
dev_pid為不通語種
dev_pid | 語言 | 模型 | 是否有標點 | 備注 |
---|---|---|---|---|
1536 | 普通話(支持簡單的英文識別) | 搜索模型 | 無標點 | 僅采樣率16000支持自定義詞庫 |
1537 | 普通話(純中文識別) | 輸入法模型 | 可以有標點 | 不支持自定義詞庫 |
1736 | 英語 | 搜索模型 | 無標點 | 不支持自定義詞庫 |
1737 | 英語 | 輸入法模型 | 可以有標點 | 不支持自定義詞庫 |
1636 | 粵語 | 搜索模型 | 無標點 | 不支持自定義詞庫 |
1637 | 粵語 | 輸入法模型 | 可以有標點 | 不支持自定義詞庫 |
1836 | 四川話 | 搜索模型 | 無標點 | 不支持自定義詞庫 |
1837 | 四川話 | 輸入法模型 | 可以有標點 | 不支持自定義詞庫 |
token參數的獲取:
使用Client Credentials獲取Access Token需要應用在其服務端發送請求(推薦用POST方法)到百度OAuth2.0授權服務的“ https://openapi.baidu.com/oauth/2.0/token ”地址上,並帶上以下參數:
- grant_type:必須參數,固定為“client_credentials”;
- client_id:必須參數,應用的 API Key;
- client_secret:必須參數,應用的 Secret Key;
** 例如:**
https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=Va5yQRHl********LT0vuXV4&client_secret= 0rDSjzQ20XUj5i********PQSzr5pVw2&
我們只需利用requests模塊發送post請求到拼出來的url就可以了。
import requests #獲取tokent baidu_server = "https://openapi.baidu.com/oauth/2.0/token?" grant_type = "client_credentials" #API Key client_id = "qRHV7hrxj8vtAGuZOpG0zW58" #Secret Key client_secret = "Bg3Bmx3uPeCUnvuHxnS16HLnNiVPuPnz" #拼url url ="%sgrant_type=%s&client_id=%s&client_secret=%s"%(server,grant_type,client_id,client_secret) print(url) #獲取token res = requests.post(url) print(res.text) token = json.loads(res.text)["access_token"] print(token)
#24.b891f76f5d48c0b9587f72e43b726817.2592000.1524124117.282335-10958516
然后拼湊json數據
#設置格式 RATE = "16000" FORMAT = "amr" CUID="wate_play" DEV_PID="1536" #以字節格式讀取文件之后進行編碼 with open(r'C:\Users\Administrator\Desktop\16k-23850.amr', "rb") as f: speech = base64.b64encode(f.read()).decode('utf8') size = os.path.getsize(r'C:\Users\Administrator\Desktop\16k-23850.amr') headers = { 'Content-Type' : 'application/json'} url = "https://vop.baidu.com/server_api" data={ "format":FORMAT, "rate":RATE, "dev_pid":DEV_PID, "speech":speech, "cuid":CUID, "len":size, "channel":1, "token":token, } req = requests.post(url,json.dumps(data),headers) result = json.loads(req.text) print(result["result"][0])
運行出結果!
示例音頻文件下載:http://speech-doc.gz.bcebos.com/rest-api-asr/public_audio/16k.pcm
speech-doc.gz.bcebos.com/rest-api-asr/public_audio/16k.wav
speech-doc.gz.bcebos.com/rest-api-asr/public_audio/16k-23850.amr
-----------------------------------------------------------------------------------------------------
第二階段,利用python的 PyAudio 模塊,進行錄音
參考文檔:http://old.sebug.net/paper/books/scipydoc/wave_pyaudio.html#pymediamp3
WAV是Microsoft開發的一種聲音文件格式,雖然它支持多種壓縮格式,不過它通常被用來保存未壓縮的聲音數據(PCM脈沖編碼調制)。WAV有三個重要的參數:聲道數、取樣頻率和量化位數。
- 聲道數:可以是單聲道或者是雙聲道
- 采樣頻率:一秒內對聲音信號的采集次數,常用的有8kHz, 16kHz, 32kHz, 48kHz, 11.025kHz, 22.05kHz, 44.1kHz
- 量化位數:用多少bit表達一次采樣所采集的數據,通常有8bit、16bit、24bit和32bit等幾種
理論知識不多說了,上面鏈接中都有的。直接上代碼。。
import wave from pyaudio import PyAudio,paInt16 import json import base64 import os import requests import time RATE = "16000" FORMAT = "wav" CUID="wate_play" DEV_PID="1536" framerate=16000 NUM_SAMPLES=2000 channels=1 sampwidth=2 TIME=2 def get_token(): server = "https://openapi.baidu.com/oauth/2.0/token?" grant_type = "client_credentials" #API Key client_id = "qRHV7hrxj8vtAGuZOpG0zW58" #Secret Key client_secret = "Bg3Bmx3uPeCUnvuHxnS16HLnNiVPuPnz" #拼url url ="%sgrant_type=%s&client_id=%s&client_secret=%s"%(server,grant_type,client_id,client_secret) #獲取token res = requests.post(url) token = json.loads(res.text)["access_token"] return token def get_word(token): with open(r'C:\Users\Administrator\Desktop\01.wav', "rb") as f: speech = base64.b64encode(f.read()).decode('utf8') size = os.path.getsize(r'C:\Users\Administrator\Desktop\01.wav') headers = { 'Content-Type' : 'application/json'} url = "https://vop.baidu.com/server_api" data={ "format":FORMAT, "rate":RATE, "dev_pid":DEV_PID, "speech":speech, "cuid":CUID, "len":size, "channel":1, "token":token, } req = requests.post(url,json.dumps(data),headers) result = json.loads(req.text) print(result) ret=result["result"][0] return result def save_wave_file(filename,data): '''save the date to the wavfile''' wf=wave.open(filename,'wb') wf.setnchannels(channels) wf.setsampwidth(sampwidth) wf.setframerate(framerate) wf.writeframes(b"".join(data)) wf.close() def my_record(): pa=PyAudio() stream=pa.open(format = paInt16,channels=1, rate=framerate,input=True, frames_per_buffer=NUM_SAMPLES) my_buf=[] count=0 print('.') while count<TIME*10:#控制錄音時間 string_audio_data = stream.read(NUM_SAMPLES) my_buf.append(string_audio_data) count+=1 save_wave_file('01.wav',my_buf) stream.close() chunk=2014 def play(): wf=wave.open(r"01.wav",'rb') p=PyAudio() stream=p.open(format=p.get_format_from_width(wf.getsampwidth()),channels= wf.getnchannels(),rate=wf.getframerate(),output=True) while True: data=wf.readframes(chunk) if data=="":break stream.write(data) stream.close() p.terminate() if __name__ == '__main__': while True: time.sleep(5) my_record() token=get_token() try: ret = get_word(token) except: print('失敗了') print(ret)
循環錄音,識別准確性還算不錯,可以把常用的詞放到txt中上傳到,百度雲應用中增加識別優先級。