原文:https://blog.csdn.net/weixin_44638960/article/details/96979347
百度AI的連接地址:https://ai.baidu.com/
1、百度AI語(yǔ)音識(shí)別技術(shù):百度語(yǔ)音識(shí)別通過 REST API 的方式給開發(fā)者提供一個(gè)通用的 HTTP 接口。上傳需要完整的錄音文件,錄音時(shí)長(zhǎng)不超過60s。對(duì)于任意操作系統(tǒng),任意編程語(yǔ)言,只要可以對(duì)百度語(yǔ)音服務(wù)器發(fā)起http請(qǐng)求的,均可以使用此接口。
首先我們學(xué)習(xí)百度給的語(yǔ)音識(shí)別demo:https://ai.baidu.com/docs#/ASR-Online-Python-SDK/top
第一步安裝python sdk:執(zhí)行 pip install baidu-aip 命令。(PyCharm直接在File-Setting中搜索baidu-aip導(dǎo)入即可)
第二步新建AipSpeech:AipSpeech是語(yǔ)音識(shí)別的Python SDK客戶端,為使用語(yǔ)音識(shí)別的開發(fā)人員提供了一系列的交互方法。
新建AipSpeech代碼如下:(APP_ID,API_KEY,SECRET_KEY均在創(chuàng)建應(yīng)用時(shí)都會(huì)給出)
from aip import AipSpeech
''' 你的 APPID AK SK '''
APP_ID = '你的 App ID'
API_KEY = '你的 Api Key'
SECRET_KEY = '你的 Secret Key'
client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
第三步對(duì)語(yǔ)音文件進(jìn)行識(shí)別:client.asr('speech','format’,'rate’,'dev_pid'),speech為建立包含語(yǔ)音內(nèi)容的Buffer對(duì)象, 語(yǔ)音文件的格式,pcm 或者 wav 或者 amr。不區(qū)分大小寫;format為音頻文件格式,pcm 或者 wav 或者 amr。不區(qū)分大小寫。推薦pcm文件;rate為采樣率,16000,固定值;dev_pid為輸入法模型(默認(rèn)1537),下圖為dev_pid的取樣表。
dev_pid | 語(yǔ)言 | 模型 | 是否有標(biāo)點(diǎn) | 備注 |
---|---|---|---|---|
1536 | 普通話(支持簡(jiǎn)單的英文識(shí)別) | 搜索模型 | 無(wú)標(biāo)點(diǎn) | 支持自定義詞庫(kù) |
1537 | 普通話(純中文識(shí)別) | 輸入法模型 | 有標(biāo)點(diǎn) | 支持自定義詞庫(kù) |
1737 | 英語(yǔ) | 有標(biāo)點(diǎn) | 不支持自定義詞庫(kù) | |
1637 | 粵語(yǔ) | 有標(biāo)點(diǎn) | 不支持自定義詞庫(kù) | |
1837 | 四川話 | 有標(biāo)點(diǎn) | 不支持自定義詞庫(kù) | |
1936 | 普通話遠(yuǎn)場(chǎng) | 遠(yuǎn)場(chǎng)模型 | 有標(biāo)點(diǎn) | 不支持 |
語(yǔ)音識(shí)別代碼如下:
# 讀取文件
def get_file_content(filePath):
with open(filePath, 'rb') as fp:
return fp.read()
# 識(shí)別本地文件
client.asr(get_file_content('audio.pcm'), 'pcm', 16000, {'dev_pid': 1536})
語(yǔ)音識(shí)別 返回?cái)?shù)據(jù)參數(shù)詳情:client.asr()返回的是一個(gè)字典類型。(下表為返回字典對(duì)應(yīng)鍵的名稱與作用)
參數(shù) | 類型 | 是否一定輸出 | 描述 |
---|---|---|---|
err_no | int | 是 | 錯(cuò)誤碼(0為返回成功) |
err_msg | int | 是 | 錯(cuò)誤碼描述 |
sn | int | 是 | 語(yǔ)音數(shù)據(jù)唯一標(biāo)識(shí),系統(tǒng)內(nèi)部產(chǎn)生,用于 debug |
result | int | 是 | 識(shí)別結(jié)果數(shù)組,提供1-5 個(gè)候選結(jié)果,string 類型為識(shí)別的字符串, utf-8 編碼 |
返回成功與失敗樣例:(result為錄音文件的識(shí)別內(nèi)容,用戶可通過此鍵來獲取)
錯(cuò)誤類型:由err_no可以推斷出錯(cuò)誤類型
錯(cuò)誤碼 | 用戶輸入/服務(wù)端 | 含義 | 一般解決方法 |
---|---|---|---|
3300 | 用戶輸入錯(cuò)誤 | 輸入?yún)?shù)不正確 | 請(qǐng)仔細(xì)核對(duì)文檔及參照demo,核對(duì)輸入?yún)?shù) |
3301 | 用戶輸入錯(cuò)誤 | 音頻質(zhì)量過差 | 請(qǐng)上傳清晰的音頻 |
3302 | 用戶輸入錯(cuò)誤 | 鑒權(quán)失敗 | token字段校驗(yàn)失敗。請(qǐng)使用正確的API_KEY 和 SECRET_KEY生成。或QPS、調(diào)用量超出限額?;蛞纛l采樣率不正確(可嘗試更換為16k采樣率)。 |
3303 | 服務(wù)端問題 | 語(yǔ)音服務(wù)器后端問題 | 請(qǐng)將api返回結(jié)果反饋至論壇或者QQ群 |
3304 | 用戶請(qǐng)求超限 | 用戶的請(qǐng)求QPS超限 | 請(qǐng)降低識(shí)別api請(qǐng)求頻率 (qps以appId計(jì)算,移動(dòng)端如果共用則累計(jì)) |
3305 | 用戶請(qǐng)求超限 | 用戶的日pv(日請(qǐng)求量)超限 | 請(qǐng)“申請(qǐng)?zhí)岣吲漕~”,如果暫未通過,請(qǐng)降低日請(qǐng)求量 |
3307 | 服務(wù)端問題 | 語(yǔ)音服務(wù)器后端識(shí)別出錯(cuò)問題 | 目前請(qǐng)確保16000的采樣率音頻時(shí)長(zhǎng)低于30s。如果仍有問題,請(qǐng)將api返回結(jié)果反饋至論壇或者QQ群 |
3308 | 用戶輸入錯(cuò)誤 | 音頻過長(zhǎng) | 音頻時(shí)長(zhǎng)不超過60s,請(qǐng)將音頻時(shí)長(zhǎng)截取為60s以下 |
3309 | 用戶輸入錯(cuò)誤 | 音頻數(shù)據(jù)問題 | 服務(wù)端無(wú)法將音頻轉(zhuǎn)為pcm格式,可能是長(zhǎng)度問題,音頻格式問題等。 請(qǐng)將輸入的音頻時(shí)長(zhǎng)截取為60s以下,并核對(duì)下音頻的編碼,是否是16K, 16bits,單聲道。 |
3310 | 用戶輸入錯(cuò)誤 | 輸入的音頻文件過大 | 語(yǔ)音文件共有3種輸入方式: json 里的speech 參數(shù)(base64后); 直接post 二進(jìn)制數(shù)據(jù),及callback參數(shù)里url。 分別對(duì)應(yīng)三種情況:json超過10M;直接post的語(yǔ)音文件超過10M;callback里回調(diào)url的音頻文件超過10M |
3311 | 用戶輸入錯(cuò)誤 | 采樣率rate參數(shù)不在選項(xiàng)里 | 目前rate參數(shù)僅提供16000,填寫4000即會(huì)有此錯(cuò)誤 |
3312 | 用戶輸入錯(cuò)誤 | 音頻格式format參數(shù)不在選項(xiàng)里 | 目前格式僅僅支持pcm,wav或amr,如填寫mp3即會(huì)有此錯(cuò)誤 |
2、語(yǔ)音讀取(目的:將用戶所講內(nèi)容打印至客戶端):
PyAudio的應(yīng)用和使用,此第三方庫(kù)可以進(jìn)行錄音,播放,生成wav文件等等。
第一步安裝PyAudio:PyCharm直接在File-Setting中搜索PyAudio導(dǎo)入,同導(dǎo)入百度AI類似。
第二步
實(shí)現(xiàn)對(duì)于音頻文件的錄制(wave庫(kù)和PyAudio庫(kù)的使用):
音頻文件的錄制:
from pyaudio import PyAudio,paInt16
import wave,time
def SaveVoice():
pa=PyAudio()
wf=wave.open(r'T.wav','wb')#打開wave文件
wf.setnchannels(1)#配置聲道數(shù)
wf.setsampwidth(2)# 采樣寬度2bytes
wf.setframerate(16000)#采樣率
stream=pa.open(format=paInt16,channels=wf.getnchannels(),rate=wf.getframerate(),input=True,frames_per_buffer=1024) #打開一個(gè)stream
buff=[]#存儲(chǔ)聲音信息
start=time.time()#開始運(yùn)行時(shí)間戳
print('say:')
while time.time()<start+6:#錄制6秒
buff.append(stream.read(wf.getframerate()))
stream.close()#關(guān)閉stream
pa.terminate()
wf.writeframes(b''.join(buff))
wf.close()#關(guān)閉wave
或者使用第三方庫(kù)SpeechRecognition :pip install SpeechRecognition即可
def my_record(rate=16000):
r = sr.Recognizer()
with sr.Microphone(sample_rate=rate) as source:
print('please say something')
audio = r.listen(source)#讀入聲音信息
with open('T.wav', 'wb') as f:
f.write(audio.get_wav_data())#得到wave信息寫入音頻文件
print('錄音完成!')
3、構(gòu)建一個(gè)機(jī)器人(圖靈機(jī)器):連接http://www.turingapi.com/
申請(qǐng)一個(gè)賬號(hào)即可免費(fèi)創(chuàng)建屬于自己的機(jī)器人(可在官網(wǎng)上對(duì)其屬性進(jìn)行設(shè)置),普通注冊(cè)用戶一天可以免費(fèi)調(diào)用100次。
使用說明:1、編碼方式UTF-8;2、接口地址:http://openapi.tuling123.com/openapi/api/v2
3、請(qǐng)求方式:http post;4、參數(shù)格式:json格式;(具體屬性的參數(shù)說明詳見下表)
{
'reqType':0,#數(shù)據(jù)類型為整型,用于區(qū)分傳入的數(shù)據(jù)類型,0-文本(默認(rèn))、1-圖片、2-音頻
'perception': {#必填項(xiàng),用戶輸入的數(shù)據(jù)
'inputText': {#非必填項(xiàng),用于保存文本信息
'text': ''#string類型,必填項(xiàng),文本內(nèi)容
},
'inputImage': {#非必填項(xiàng),用于保存圖片信息
'url': 'imageUrl'#string類型,必填項(xiàng),圖片地址
},
'selfInfo': {#非必填項(xiàng),用于識(shí)別用戶信息
'location': {
'city': '',
'province': '',
'street': ''
}
}
},
'userInfo': {#必填項(xiàng),識(shí)別用戶信息
'apiKey': '',#此處為圖靈機(jī)器人的apiKey
'userId': ''
}
}
參數(shù)說明
參數(shù) | 類型 | 是否必須 | 取值范圍 | 說明 |
---|---|---|---|---|
reqType | int | N | - | 輸入類型:0-文本(默認(rèn))、1-圖片、2-音頻 |
perception | - | Y | - | 輸入信息 |
userInfo | - | Y | - | 用戶參數(shù) |
perception
參數(shù) | 類型 | 是否必須 | 取值范圍 | 說明 |
---|---|---|---|---|
inputText | - | N | - | 文本信息 |
inputImage | - | N | - | 圖片信息 |
inputMedia | - | N | - | 音頻信息 |
selfInfo | - | N | - | 客戶端屬性 |
注意:輸入?yún)?shù)必須包含inputText或inputImage或inputMedia!(必須有一個(gè)存在)
inputText
參數(shù) | 類型 | 是否必須 | 取值范圍 | 說明 |
---|---|---|---|---|
text | String | Y | 1-128字符 | 直接輸入文本 |
inputImage
參數(shù) | 類型 | 是否必須 | 取值范圍 | 說明 |
---|---|---|---|---|
url | String | Y | 圖片地址 |
inputMedia
參數(shù) | 類型 | 是否必須 | 取值范圍 | 說明 |
---|---|---|---|---|
url | String | Y | 音頻地址 |
selfInfo
參數(shù) | 類型 | 是否必須 | 取值范圍 | 說明 |
---|---|---|---|---|
location | - | N | - | 地理位置信息 |
location
參數(shù) | 類型 | 是否必須 | 取值范圍 | 說明 |
---|---|---|---|---|
city | String | Y | - | 所在城市 |
province | String | N | - | 省份 |
street | String | N | - | 街道 |
userInfo
參數(shù) | 類型 | 是否必須 | 取值范圍 | 說明 |
---|---|---|---|---|
apiKey | String | Y | 32位 | 機(jī)器人標(biāo)識(shí) |
userId | String | Y | 長(zhǎng)度小于等于32位 | 用戶唯一標(biāo)識(shí) |
groupId | String | N | 長(zhǎng)度小于等于64位 | 群聊唯一標(biāo)識(shí) |
userIdName | String | N | 長(zhǎng)度小于等于64位 | 群內(nèi)用戶昵稱 |
返回成功與失敗的示例:
失敗樣例:(只返回錯(cuò)誤提示類型)
{#返回失敗信息
'intent':
{
'code':5000#錯(cuò)誤碼,0表示上傳成功。
}
}
異常碼 說明
5000 無(wú)解析結(jié)果
6000 暫不支持該功能
4000 請(qǐng)求參數(shù)格式錯(cuò)誤
4001 加密方式錯(cuò)誤
4002 無(wú)功能權(quán)限
4003 該apikey沒有可用請(qǐng)求次數(shù)
4005 無(wú)功能權(quán)限
4007 apikey不合法
4100 userid獲取失敗
4200 上傳格式錯(cuò)誤
4300 批量操作超過限制
4400 沒有上傳合法userid
4500 userid申請(qǐng)個(gè)數(shù)超過限制
4600 輸入內(nèi)容為空
4602 輸入文本內(nèi)容超長(zhǎng)(上限150)
7002 上傳信息失敗
8008 服務(wù)器錯(cuò)誤
0 上傳成功
成功樣例:以詢問酒店為例
{
'intent': {#用于表示請(qǐng)求意圖
'code': 10005,
'intentName': '',
'actionName': '',
'parameters': {
'nearby_place': '酒店'
}
},
'results': [#輸出結(jié)果集合
{
'groupType': 1,
'resultType': 'url',
'values': {
'url': 'http://m.elong.com/hotel/0101/nlist/#indate=2016-12-10&outdate=2016-12-11&keywords=%E4%BF%A1%E6%81%AF%E8%B7%AF'
}
},
{
'groupType': 1,
'resultType': 'text',
'values': {#輸出值
'text': '親,已幫你找到相關(guān)酒店信息'#機(jī)器反饋信息
}
}
]
}
參數(shù)說明
參數(shù) | 類型 | 是否必須 | 取值范圍 | 說明 |
---|---|---|---|---|
intent | - | Y | - | 請(qǐng)求意圖 |
results | - | N | - | 輸出結(jié)果集 |
intent
參數(shù) | 類型 | 是否包含 | 取值范圍 | 說明 |
---|---|---|---|---|
code | int | Y | - | 輸出功能code |
intentName | String | N | - | 意圖名稱 |
actionName | String | N | - | 意圖動(dòng)作名稱 |
parameters | Map | N | - | 功能相關(guān)參數(shù) |
results
參數(shù) | 類型 | 是否包含 | 取值范圍 | 說明 |
---|---|---|---|---|
resultType | String | Y | 文本(text);連接(url);音頻(voice);視頻(video);圖片(image);圖文(news) | 輸出類型 |
values | - | Y | - | 輸出值 |
groupType | int | Y | - | '組’編號(hào):0為獨(dú)立輸出,大于0時(shí)可能包含同組相關(guān)內(nèi)容 (如:音頻與文本為一組時(shí)說明內(nèi)容一致) |
通過requests庫(kù)的post方法將json數(shù)據(jù)和編碼格式UTF-8(import requests)
import requests#導(dǎo)入requests庫(kù),多用于網(wǎng)絡(luò)爬蟲
import json#導(dǎo)入json庫(kù)
TulingUrl='http://openapi.tuling123.com/openapi/api/v2'
turing_api_key = '你申請(qǐng)的圖靈機(jī)器人id'
def RobotSpeak(usersay='你好'):#默認(rèn)為對(duì)話你好
robot={
'perception': {
'inputText': {
'text': usersay#用戶詢問內(nèi)容
}
},
'userInfo': {
'apiKey': turing_api_key ,
'userId': 'Dudu'#識(shí)別用戶可隨機(jī)書寫
}
}
response=json.loads(requests.post(TulingUrl,None,robot,headers={'Content-Type':'charset=UTF-8'}).text)
print(response)
if __name__=='__main__':
RobotSpeak('你叫什么名字')
到此位置我們基本可以實(shí)現(xiàn)簡(jiǎn)單的人機(jī)交互功能,即用戶說一句話機(jī)器給出相應(yīng)的答復(fù),但僅僅是文字的輸入輸出似乎滿足不了我們的需求,我們可以在此基礎(chǔ)上擴(kuò)展新的功能,比如讓機(jī)器將反饋的信息以語(yǔ)音的形式得以呈現(xiàn)。
Python給我們提供了一個(gè)第三方庫(kù)pyttsx,可以實(shí)現(xiàn)文字轉(zhuǎn)換語(yǔ)音的基本功能。
import pyttsx3#導(dǎo)入第三方庫(kù)
engine=pyttsx3.init()#初始化engine
rate = engine.getProperty('rate')
engine.setProperty('rate', rate-66)#設(shè)置語(yǔ)速
engine.say('要說的內(nèi)容')
engine.runAndWait()#沒有此句無(wú)聲音
from aip import AipSpeech
from pyaudio import PyAudio,paInt16
import requests,json,wave,time,pyttsx3
#百度AI,配置信息
APP_ID = ''#百度ai應(yīng)用id
API_KEY = ''#百度ai應(yīng)用的鍵值
SECRET_KEY = ''
client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
#圖靈機(jī)器,配置信息
TulingUrl='http://openapi.tuling123.com/openapi/api/v2'
turing_api_key = ''#圖靈機(jī)器人api_key
# 讀取文件
def get_file_content(filePath):
with open(filePath, 'rb') as fp:
return fp.read()
#用戶語(yǔ)音輸入
def SaveVoice():
pa=PyAudio()
wf=wave.open(r'T.wav','wb')#打開wave文件
wf.setnchannels(1)#配置聲道數(shù)
wf.setsampwidth(2)# 采樣寬度2bytes
wf.setframerate(16000)#采樣率
stream=pa.open(format=paInt16,channels=wf.getnchannels(),rate=wf.getframerate(),input=True,frames_per_buffer=1024) #打開一個(gè)stream
buff=[]#存儲(chǔ)聲音信息
start=time.time()#開始運(yùn)行時(shí)間戳
print('用戶說:')
while time.time()<start+6:#錄制6秒
buff.append(stream.read(wf.getframerate()))
stream.close()#關(guān)閉stream
pa.terminate()
wf.writeframes(b''.join(buff))
wf.close()#關(guān)閉wave
#接受機(jī)器人響應(yīng)
def RobotSpeakText(usersay='你好'):
robot={
'perception': {
'inputText': {
'text': usersay
}
},
'userInfo': {
'apiKey': turing_api_key ,
'userId': 'Dudu'
}
}
response=json.loads(requests.post(TulingUrl,None,robot,headers={'Content-Type':'charset=UTF-8'}).text)
return str(response['results'][0]['values']['text'])
#語(yǔ)音發(fā)聲
def RobotVoice(robotsay='我沒聽清,你在說一遍'):
engine=pyttsx3.init()
rate=engine.getProperty('rate')
engine.setProperty('rate',rate-66)
engine.say(robotsay)
engine.runAndWait()
#主函數(shù)
def main():
while True:
try:
SaveVoice()
result = client.asr(get_file_content('T.wav'), 'wav', 16000, {'dev_pid': 1536}) # 識(shí)別本地文件
usersay=result['result'][0]
print(usersay)
robotsay=RobotSpeakText(usersay)
print('小嘟嘟說:')
print(robotsay)
RobotVoice(robotsay)
except:#異常處理
break
if __name__=='__main__':
main()
聯(lián)系客服