title: 單片機(jī)學(xué)習(xí):第一篇 基于Python的樹莓派語音助手 tags: 樹莓派,python,語音助手,百度AIP
樹莓派功能十分強(qiáng)大,作為一個(gè)微型電腦,獨(dú)特的陣腳設(shè)計(jì)使得樹莓派開發(fā)的自定義程度非常高。本篇博客通過使用python語言,封裝一個(gè)簡單的語音助手程序。制作一個(gè)語音助手你需要如下物品: ``` 1:一個(gè)樹莓派(3代、4代皆可) 2:免驅(qū)的usb聲卡(聲卡需接在樹莓派usb接口) 3:麥克風(fēng)(接在聲卡上) 4:有線音響(音響可連在聲卡上,也可連在樹莓派的3.5mm接口上) (樹莓派播放設(shè)備默認(rèn)使用3.5mm接口,具體過程需要自定義播放設(shè)備) ``` 如果要設(shè)置usb聲卡輸出,參考配置聲卡教程:https://www.jianshu.com/p/f414b85b9e71,如果使用默認(rèn)3.5mm接口輸出可以忽略。 設(shè)計(jì)語音助手有如下過程:錄音、語音識別、圖靈機(jī)器人對話、語音合成,以下對各個(gè)過程進(jìn)行介紹。
一、pyaudio錄音
使用python語言進(jìn)行錄音,主要是將說話者聲音輸出成一段音頻文件。對于python來說,這很容易。通過引用pyaudio庫,可以進(jìn)行錄音、播放、生成wav文件等。 首先,我們在樹莓派上需要下載pyaudio庫: ```pip3 install pyaudio``` 在pyaudio的官網(wǎng)http://people.csail./hubert/pyaudio/介紹上有對pyaudio的詳細(xì)介紹,以官網(wǎng)示例: 創(chuàng)建一名為rec的python文件 ```sudo nano rec.py```
# 隱藏錯(cuò)誤消息,因?yàn)闀?huì)有一堆ALSA和JACK錯(cuò)誤消息,但其實(shí)能正常錄音 # os.close(sys.stderr.fileno()) BUTT = 26 # 開始錄音的按鈕:一邊接GPIO26,一邊接地 # 設(shè)GPIO26腳為輸入腳,電平拉高,也就是說26腳一旦讀到低電平,說明按了按鈕 GPIO.setup(BUTT, GPIO.IN, pull_up_down = GPIO.PUD_UP) # wav文件是由若干個(gè)CHUNK組成的,CHUNK我們就理解成數(shù)據(jù)包或者數(shù)據(jù)片段。 FORMAT = pyaudio.paInt16 # pyaudio.paInt16表示我們使用量化位數(shù) 16位來進(jìn)行錄音 WAVE_OUTPUT_FILENAME = 'command.wav' GPIO.wait_for_edge(BUTT, GPIO.FALLING) # To use PyAudio, first instantiate PyAudio using pyaudio.PyAudio(), which sets up the portaudio system. stream = p.open(format = FORMAT, channels = 1, # cloud speecAPI只支持單聲道 frames_per_buffer = CHUNK) while GPIO.input(BUTT) == 0: data = stream.read(CHUNK) print('錄音完成,輸出文件:' + WAVE_OUTPUT_FILENAME + '\n') wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb') wf.setsampwidth(p.get_sample_size(FORMAT)) # Returns the size (in bytes) for the specified sample format. wf.writeframes(b''.join(frames)) # 可以直接運(yùn)行rec.py進(jìn)行測試,同時(shí)保證該文件import時(shí)不會(huì)自動(dòng)運(yùn)行 if __name__ == '__main__':
通過樹莓派一 點(diǎn)亮LED燈:https://www./2020/06/21/raspberry/?from=timeline,我們對樹莓派的陣腳已經(jīng)有了大概了解。 按鈕錄音,是通過按鈕控制陣腳高低電平。在上述代碼里引用```import RPi.GPIO as GPIO```,選擇26號輸出腳和GND。 執(zhí)行后按住按鈕開始錄音,會(huì)在rec.py同目錄下生成command.wav文件。
二、語音識別
我選擇了百度AIP平臺,使用其語音識別技術(shù)。(當(dāng)然也可使用Google、科大訊飛等平臺) 1. 申請百度AIP賬號與應(yīng)用 在百度AI開發(fā)平臺:https://ai.baidu.com/?track=cp:aipinzhuan|pf:pc|pp:AIpingtai|pu:title|ci:|kw:10005792注冊賬號,再在控制臺創(chuàng)建一個(gè)新應(yīng)用 2. python調(diào)用百度AIP 官網(wǎng)文檔中有詳細(xì)使用語音識別技術(shù),包括python的示例。首先導(dǎo)入AipSpeech, 即百度AI語音識別的Python SDK客戶端(```pip3 install baidu-aip```)。附上代碼如下:
from aip import AipSpeech SECRET_KEY = '你的secret_key' client = AipSpeech(APP_ID, API_KEY, SECRET_KEY) def get_file_content(filePath): #filePath待讀取文件名 with open(filePath, 'rb') as fp: result = client.asr(get_file_content(filename), {'dev_pid': 1537,} # dev_pid 參數(shù)表示識別的語 言類型 1537表示普通話 if result['err_msg']=='success.': word = result['result'][0].encode('utf-8') # utf-8 編碼 if word[len(word)-3:len(word)]==',': print (word[0:len(word)-3]) with open('demo.txt','wb') as f: f.write(word[0:len(word)-3]) print (word.decode('utf-8').encode('gbk')) with open('demo.txt','wb') as f: print ('音頻文件不存在或格式錯(cuò)誤') # main 函數(shù) 識別本地錄音文件 yahboom.wav if __name__ == '__main__': stt('command.wav') # command.wav為待讀取文件,請?zhí)鎿Q
三、與圖靈機(jī)器人對話
使用圖靈機(jī)器人基本原理就是使用urllib.request模塊,向接口地址發(fā)送HTTP POST請求,請求中加入了聊天內(nèi)容。(返回內(nèi)容是一個(gè)字典) 首先我們需要申請一個(gè)機(jī)器人:官網(wǎng)入口:http://www./ python代碼參考:
api_url = 'http://openapi./openapi/api/v2' 'apiKey': 'xxxxxxxxxxxxx', #你的key 'userId': '123' #唯一的標(biāo)識,自選即可 # 將字典格式的req轉(zhuǎn)為utf8編碼的字符串 req = json.dumps(req).encode('utf8') print('\n' + '正在調(diào)用圖靈機(jī)器人API...') http_post = urllib.request.Request(api_url, data=req, headers={'content-type': 'application/json'}) response = urllib.request.urlopen(http_post) response_str = response.read().decode('utf8') response_dic = json.loads(response_str) intent_code = response_dic['intent']['code'] if(intent_code == 10023): results_url = response_dic['results'][0]['values']['url'] results_text = response_dic['results'][1]['values']['text'] with open('result.txt','w') as f: f.write(results_text) # 自帶文件關(guān)閉功能,不需要再寫f.close() answer = {'code': intent_code, 'text': results_text, 'url':results_url} results_text = response_dic['results'][0]['values']['text'] answer = {'code': intent_code, 'text': results_text} with open('result.txt','w') as f: f.write(results_text) # 自帶文件關(guān)閉功能,不需要再寫f.close() if __name__ == '__main__': with open('demo.txt', 'r',encoding='UTF-8') as f:
四、語音合成
我同樣選擇了百度的語音合成(注意,AI平臺新建應(yīng)用后,語音合成技術(shù)需要自行領(lǐng)用。語音識別的key與合成的key不一樣,使用請注意)。示例文檔自行參考,提供參考代碼:
from aip import AipSpeech API_KEY = 'xxxxxxxxxxxxxxxx' SECRET_KEY = 'chMdMAS0acD7sPS6FhP3a3iOijU7wMVl' client = AipSpeech(APP_ID, API_KEY, SECRET_KEY) result = client.synthesis(texts , options={'vol':5}) print('\n' + '正在調(diào)用語音合成API...') if not isinstance(result,dict): with open('answer.mp3','wb') as f: print('以下均為mplayer的輸出內(nèi)容\n') os.system('mplayer answer.mp3') if __name__ == '__main__': with open('result.txt', 'rb') as f: # 打開文件
五、封裝
至此,我們的錄音、識別、對話、合成已經(jīng)完成了,開始對這四個(gè)py文件進(jìn)行封裝。 在封裝時(shí),增加一個(gè)獲取獲取歌曲直鏈url1.py文件。 一個(gè)簡單的if else 完成了圖靈機(jī)器人對話到在線放歌的切換。 當(dāng)然,讀者還可以進(jìn)一步完善,例如實(shí)現(xiàn)與圖靈機(jī)器人的多次對話直到退出。
需要參考我的全部代碼,可以去我的資源下載
|