馮江惠 王穎潔 王志軍
摘要:為了提升老年人等特殊群體對(duì)手機(jī)的使用效果,使中老年人更方便地使用手機(jī),為了方便人們?cè)诓贿m合聽語音的場(chǎng)合通過文字及時(shí)獲取信息,研究了基于Android系統(tǒng)的手機(jī)語音記錄器。采用Android應(yīng)用開發(fā),將語音轉(zhuǎn)文字、語音記錄、即時(shí)通訊、語音轉(zhuǎn)發(fā)和語音的云存儲(chǔ)結(jié)合起來,構(gòu)成一套完整的語音交流、共享平臺(tái)。基于Android的應(yīng)用可以搭載到絕大多數(shù)手機(jī)上,具有開放、分享、高整合的優(yōu)點(diǎn)。
關(guān)鍵詞:Android系統(tǒng);語音轉(zhuǎn)文字;即時(shí)通訊
語音識(shí)別是人工智能和機(jī)器學(xué)習(xí)應(yīng)用的一個(gè)重要方向,近年來,語音識(shí)別技術(shù)突飛猛進(jìn),大量產(chǎn)品被開發(fā)并應(yīng)用到實(shí)際。前不久,微信App中就有了一個(gè)語音轉(zhuǎn)文字的重大更新,長(zhǎng)按語音文件,點(diǎn)擊“轉(zhuǎn)換為文字”,就可以進(jìn)行識(shí)別,給不方便聽語音的用戶帶來了福祉。近三十年來,語音識(shí)別技術(shù)發(fā)展迅速,逐漸從實(shí)驗(yàn)室走向市場(chǎng),形成產(chǎn)品。
語音識(shí)別發(fā)展到現(xiàn)在,在中小詞匯量非特定人語音識(shí)別系統(tǒng)和特定人語音識(shí)別系統(tǒng)中的識(shí)別精度已經(jīng)接近100%,這些技術(shù)已經(jīng)能夠滿足一般應(yīng)用的需求。在信息處理、通信與電子系統(tǒng)、自動(dòng)控制等領(lǐng)域相繼出現(xiàn)了不同用途的語音識(shí)別系統(tǒng),已經(jīng)逐漸顯露出其強(qiáng)大的技術(shù)優(yōu)勢(shì)和生命力。隨著硬件技術(shù)和軟件技術(shù)的快速發(fā)展,語音識(shí)別為我們提供了一種嶄新的遠(yuǎn)景。
現(xiàn)在上線的手機(jī)應(yīng)用中有很多聊天應(yīng)用,但是缺少以語音為主的應(yīng)用,所以本文借用了百度語音的語音識(shí)別技術(shù),參考其他手機(jī)應(yīng)用的成功案例,使用Android開發(fā)技術(shù),結(jié)合Http和Mysql作為后臺(tái)服務(wù)器,制作了一個(gè)以語音為主體的手機(jī)應(yīng)用,功能包括語音錄制、語音轉(zhuǎn)文字、添加好友并進(jìn)行即時(shí)語音通信等,將語音的功能整合到一起,形成一個(gè)完整的以語音為主體的手機(jī)應(yīng)用。
系統(tǒng)的功能主要在以下三個(gè)方面:
1)語音錄制
實(shí)現(xiàn)錄制的語音在外置存儲(chǔ)卡中以PCM格式的文件長(zhǎng)期存儲(chǔ)。在語音錄制中,可以隨時(shí)暫停錄制和繼續(xù)錄制;在語音播放中,可以隨時(shí)暫停和繼續(xù)播放,且可以調(diào)整播放進(jìn)度。
2)語音到文字的轉(zhuǎn)換
通過當(dāng)前市場(chǎng)上比較成熟的百度語音開放平臺(tái)的RESTAPI實(shí)現(xiàn)。
3)即時(shí)通訊
實(shí)現(xiàn)了用戶之間的即時(shí)通訊,用戶之間可以相互發(fā)送文字消息和語音消息。
本文將介紹該系統(tǒng)實(shí)現(xiàn)所用的關(guān)鍵技術(shù),并對(duì)相應(yīng)技術(shù)進(jìn)行概括分析。
1軟件的設(shè)計(jì)
1.1設(shè)計(jì)流程圖
如圖l所示。
1.2平臺(tái)搭建
1.2.1客戶端平臺(tái)的搭建
需要用到的工具包和軟件:JDK和Android Studio需要添加的iar包及其用途:
1)Bmob短信驗(yàn)證碼API:BMobSMS-v1.0.1_20150710jar
利用Bmob后端云平臺(tái)的短信驗(yàn)證碼接口,實(shí)現(xiàn)手機(jī)短信驗(yàn)證碼功能。
2)搭建Mina框架需要用到的兩個(gè)包:mina-core-2.0.13.jar、slf4j-api-1.7.14.jar
在阻塞模式下,若從網(wǎng)絡(luò)流中讀取不到指定大小的數(shù)據(jù)量,阻塞10就在那里阻塞著。在非阻塞模式下,若從網(wǎng)絡(luò)流中讀取不到指定大小的數(shù)據(jù)量,非阻塞10就立即通行。顯然,非阻塞10比阻塞10有更高的性能,但是非阻塞式開發(fā)難度就成數(shù)倍遞增了。我們需要開啟線程專門去維護(hù)網(wǎng)絡(luò)方面的操作,讓它不影響主線程的運(yùn)行。javal.4以上有NIO網(wǎng)絡(luò)操作框架newl0,非阻塞式高伸縮性,但它的用法比較復(fù)雜,Mina和Nety,是用NIO封裝的好用的網(wǎng)絡(luò)操作框架,所以引入了Mina框架來進(jìn)行客戶端文件的上傳。
Slf4j是Simple Logging Facade for Java的全拼,是在Mina內(nèi)部用來做日志用的。
3)用于網(wǎng)絡(luò)通信的包:volley.jar
Volley是2013年Google I/O上發(fā)布的一款網(wǎng)絡(luò)框架,基于Android平臺(tái),能使網(wǎng)絡(luò)通信更快,更簡(jiǎn)單,更健全。Volley只適合數(shù)據(jù)量小,通信頻繁的網(wǎng)絡(luò)操作,不適合數(shù)據(jù)量大的,像音頻,視頻等的傳輸。
4)用于解析和打包json數(shù)據(jù)的包:fastjson-1.1.38.jar
1.2.2服務(wù)器端平臺(tái)的搭建
需要用到的工具包和軟件:Eclipse的Java EE版本,Apache Tomcat v7.0,mysql數(shù)據(jù)庫
需要添加的{ar包及其用途:
1)用于連接數(shù)據(jù)庫的包:mysql-connector-java-5.1.7-bin.jar
2)使用servlet相關(guān)的類時(shí)需要用到的包:servlet-api.jar
3)與客戶端對(duì)應(yīng)的搭建Mina框架時(shí)所用的包:mina-core-2.0.13.jar、slf4j-api-1.7.14.jar、slf4j-simple-1.7.21.jar
與客戶端相比,服務(wù)器端多了slf4i-simple-1.7.21.jar這個(gè)包,這個(gè)包是為了給類路徑添加一個(gè)綁定,如果沒有這個(gè)綁定,控制臺(tái)就會(huì)有相應(yīng)的警告,slf4i-simple-1.7.21.jar相當(dāng)于slf4j-api-1.7.14.jar的日志接口的實(shí)現(xiàn)包。
2功能的實(shí)現(xiàn)
2.1錄音功能的具體實(shí)現(xiàn)
錄音功能的實(shí)現(xiàn)過程可以通過分析錄音界面每個(gè)控件的行為來分析,錄音界面如圖2所示:
2.1.1錄音按鈕的實(shí)現(xiàn)(三種狀態(tài))
1)準(zhǔn)備狀態(tài):初次點(diǎn)擊按鈕時(shí),圖標(biāo)為●,就會(huì)得到一個(gè)AudioTrackManager對(duì)象,用來初始化存放錄音的絕對(duì)路徑,并且設(shè)置音源為麥克風(fēng),音頻采樣率為16k,聲道為單聲道,音頻采樣位數(shù)為PCM(脈沖編碼調(diào)制)16位/{羊本,設(shè)置音頻的最小緩沖區(qū)大小,并轉(zhuǎn)到錄音線程開始錄音并用Android API中擁有的類AudioRecord類的startRecord方法開始計(jì)時(shí),在這之前還要隱藏保存和播放按鈕,并且獲取音量大小。
2)暫停狀態(tài):暫停計(jì)時(shí),顯示保存按鈕和播放按鈕,修改按鈕的樣式為圖2.1,調(diào)用AudioRecord類的stop()方法暫停錄音,并調(diào)用AudioRecord類的release()方法釋放資源,如果不釋放就會(huì)一直占用資源,導(dǎo)致后來再申請(qǐng)的時(shí)候無法申請(qǐng)。
3)繼續(xù)狀態(tài):在暫停之后點(diǎn)擊繼續(xù)可以繼續(xù)進(jìn)行錄音,這時(shí)要重新開啟錄音線程,這里要判斷是否是剛剛開始錄音,如果AudioRecord未被初始化,說明是剛剛開始錄音,如果AudioRecord被初始化,則是暫停錄音之后繼續(xù)錄音,繼續(xù)錄音時(shí)要繼續(xù)進(jìn)行計(jì)時(shí),并修改圖標(biāo)樣式為●。
2.1.2退出錄音按鈕的實(shí)現(xiàn)
點(diǎn)擊退出錄音按鈕,在錄音按鈕的響應(yīng)事件中進(jìn)行相應(yīng)的操作,首先彈出對(duì)話框,提示“是否退出錄音?退出將不保存此條錄音”,如果確定退出,則將刪除當(dāng)前音頻對(duì)應(yīng)的文件及路徑信息,取消則僅僅取消對(duì)話框的顯示,不做其他操作。
2.1.3播放的實(shí)現(xiàn)
播放時(shí)主要有播放和暫停播放兩種狀態(tài),為了方便人們直觀地看出音頻播放的進(jìn)度,還設(shè)置了一個(gè)可以拖動(dòng)的滾動(dòng)條,這樣也可以方便用戶對(duì)播放進(jìn)度隨時(shí)進(jìn)行調(diào)整。播放界面的屏幕截圖如圖2.1所示
1)初次播放:點(diǎn)擊播放按鈕,在鼠標(biāo)點(diǎn)擊事件中得到該語言的路徑,并調(diào)用AudioTrack這個(gè)可以播放簡(jiǎn)單音頻資源類的play()方法,將音頻播放出來。
2)暫停播放:調(diào)用AudioTrack類的pause()方法,進(jìn)行暫停。
3)繼續(xù)播放:操作跟初次播放時(shí)相同,但播放進(jìn)度要設(shè)置為暫停時(shí)的播放進(jìn)度,這樣就可以從暫停處繼續(xù)進(jìn)行播放。
4)Seekbar滾動(dòng)條的實(shí)現(xiàn):主要需要計(jì)算好滾動(dòng)條的進(jìn)度和音頻進(jìn)度百分比的問題,根據(jù)滾動(dòng)條已拖動(dòng)的百分比計(jì)算繼續(xù)播放開始時(shí)的位置,位置的計(jì)算公式如下:
position=(int)(fileLength*1.0f*progress/100);
這里在實(shí)際設(shè)計(jì)的時(shí)候出現(xiàn)了一個(gè)問題:如果最后計(jì)算出的position的值不能被2整除,那么要讓它加1,使它能被2整除,這是因?yàn)锳udioRecord類中進(jìn)行錄音時(shí),每次讀取一個(gè)short類型的長(zhǎng)度,而short型是2個(gè)字節(jié),而且PCM采樣位數(shù)設(shè)置的是16位,即2個(gè)字節(jié),即每次讀人兩個(gè)字節(jié)的數(shù)據(jù)樣本,如果不能被2整除,播放時(shí)就會(huì)出現(xiàn)雜音。
5)柱狀頻譜圖的繪制:柱狀頻譜圖根據(jù)音量的大小繪制頻譜中的振幅,振幅的大小根據(jù)聲音的大小成正比調(diào)整,屏幕中顯示200個(gè)條形柱,更新時(shí),在handleMessage中每隔50ms更新一次界面顯示效果。
2.2語音轉(zhuǎn)文字功能的實(shí)現(xiàn)過程
調(diào)用第三方文檔:百度的REST API實(shí)現(xiàn)在線語音轉(zhuǎn)文字的功能。具體實(shí)現(xiàn)過程如下:
1)在繼承了AsyncTask的類中異步加載要發(fā)送到服務(wù)器的信息
設(shè)置請(qǐng)求方式為“POST”,并設(shè)置文件的格式、采樣頻率和長(zhǎng)度,語音數(shù)據(jù)轉(zhuǎn)換為字節(jié)序列放在HTTP-BODY中,然后發(fā)送到百度服務(wù)器,發(fā)送前要首先獲取百度的“access_token”這個(gè)驗(yàn)證字符串,獲取連接權(quán)限。
2)獲取服務(wù)器來的響應(yīng)信息
在Http響應(yīng)體中,給出了Json格式的文字,客戶端接收到Json格式的輸入流,并將其解析成字符串,再在繼承AsyncTask類的繼承類中的onPostExecute(Void avoid)方法中將文字放在handler中,顯示在界面上,最終實(shí)現(xiàn)文字到語音的轉(zhuǎn)換。
文字轉(zhuǎn)換界面和語音播放界面如下:
2.3備份文件的實(shí)現(xiàn)過程
2.3.1服務(wù)器備份(上傳)
將需要傳送的文件打包成FileObject,發(fā)送到Service中,Service默認(rèn)都在主線程中運(yùn)行,因?yàn)槿糁苯釉赟ervice中進(jìn)行發(fā)送文件等耗時(shí)操作,應(yīng)用進(jìn)程將會(huì)被掛起,甚至出現(xiàn)ANR(應(yīng)用無法響應(yīng))錯(cuò)誤,所以在Service中的onStartCommandO方法中重新開啟一個(gè)子線程,在子線程中通過IoSession發(fā)送FileObject,這個(gè)FileObject的file_type屬性設(shè)置成TYPE_BACKUP,進(jìn)行文件的傳送,服務(wù)器根據(jù)所收到文件的文件名,創(chuàng)建文件,并建立好流通信,循環(huán)接收數(shù)據(jù)包,將數(shù)據(jù)報(bào)寫入文件,當(dāng)所接收數(shù)據(jù)的長(zhǎng)度等于提前接收到的信息中的文件長(zhǎng)度,則表示接收完畢。
2.3.2本地備份
在qq、微信等即時(shí)通訊中,目前還沒有本地備份語音的功能,所以想到可以設(shè)計(jì)一個(gè)本地備份的功能,方便隨時(shí)查看、分享語音文件。
本地備份就是開啟一個(gè)子線程,將文件通過DbHelper這個(gè)SQLite數(shù)據(jù)庫幫助類寫入到SD卡中。
2.4即時(shí)通訊的實(shí)現(xiàn)過程
要進(jìn)行即時(shí)通訊,首先要注冊(cè)賬號(hào)并登錄,截圖如下:
登錄之后主要有兩個(gè)方面:
1)添加好友
將要添加好友的手機(jī)號(hào)通過Service中的子線程發(fā)送給服務(wù)器端,服務(wù)器從數(shù)據(jù)庫首先確認(rèn)是否有該用戶字段。如果有,就將此條消息通過Notification通知發(fā)送給對(duì)方,對(duì)方接受請(qǐng)求后,發(fā)送一個(gè)響應(yīng)給服務(wù)器,服務(wù)器再更新當(dāng)前用戶的好友列表;如果沒有該用戶字段,就將反饋消息發(fā)送給用戶,用戶界面顯示相應(yīng)的提示信息。
鎖屏情況下添加好友,也是直接發(fā)送Notification通知給對(duì)方。
2)發(fā)送消息
發(fā)送消息可以是先用戶A直接通過服務(wù)器發(fā)送過來的用戶B的IP地址、TCP端口號(hào)等信息,直接向用戶B的PC機(jī)發(fā)出聊天信息,用戶B的IM客戶端軟件收到后顯示在屏幕上,然后用戶B再直接回復(fù)到用戶A的PC機(jī),這樣雙方的即時(shí)文字消息就不通過IM服務(wù)器中轉(zhuǎn),而是通過網(wǎng)絡(luò)進(jìn)行點(diǎn)對(duì)點(diǎn)的直接通訊,這稱為對(duì)等通訊方式(Peer To Peer),也可以是每次發(fā)送信息都經(jīng)過服務(wù)器中轉(zhuǎn),這樣就可以解決用戶A與用戶B的點(diǎn)對(duì)點(diǎn)通訊由于防火墻、網(wǎng)絡(luò)速度等原因難以建立或者速度很慢的問題,這里用的是通過服務(wù)器中轉(zhuǎn)的方式。
發(fā)送消息時(shí),用戶A先通過socket與服務(wù)器取得連接,服務(wù)器獲得用戶A的Id、要發(fā)送的信息和用戶B的Id,然后把消息打包發(fā)送給用戶B,用戶B如果想要發(fā)送消息給用戶A,也是同樣的過程。
發(fā)送消息時(shí),手機(jī)界面當(dāng)前所處的情況有多種,也要分別討論:
1)手機(jī)界面停在當(dāng)前聊天界面:更新當(dāng)前界面聊天信息。
2)手機(jī)界面停留在好友列表界面:在對(duì)應(yīng)的好友右側(cè)顯示未讀消息數(shù),當(dāng)點(diǎn)開聊天界面時(shí)更新界面聊天信息。
3)本應(yīng)用的其他界面和非本應(yīng)用的其他界面:發(fā)送Notification通知,提醒用戶查看消息。
4)鎖屏界面:發(fā)送Notification通知,而且對(duì)方要首先獲取好友昵稱稱,以便開鎖后直接進(jìn)入聊天界面。
3結(jié)束語
當(dāng)下語音交互在即時(shí)通訊方面得到了足夠的重視,語音識(shí)別技術(shù)在人機(jī)交互中成為非常重要的方式,語音交互極大地提高了人們的交互速度,了解并學(xué)習(xí)語音交互相關(guān)的技術(shù),對(duì)未來在語音領(lǐng)域有更多的了解和深入有很大的幫助。本文介紹了一個(gè)相對(duì)完整的語音聊天工具,對(duì)文件的存儲(chǔ)、文件的上傳、消息的發(fā)送做了相應(yīng)的研究,對(duì)語音的錄制、播放、發(fā)送功能做了略為系統(tǒng)的闡述,幫助鞏固和系統(tǒng)地運(yùn)用已有的知識(shí),未來在語音技術(shù)的研究上還需繼續(xù)努力,不斷前行。