最近要寫一個以語音發出指令,然後利用手機控制馬達的程式,現在 MIT App Inventor 中的 Media 就內建有 SpeechRecognizer 語音辨識的積木可以來構建我需要的功能。
看 SpeechRecognizer 的線上說明,只要將 UseLegacy 的屬性值改為 False,就可以讓語音辨識的功能在背景執行,而且可以連續地使用,直到關閉功能為止。這部份和舊版時,想要不中斷使用語音辨識,得利用 Timer 來自己判斷並維運,有很大的差異。
但是我試了兩天,並不是像說明寫的那麼簡單啊!無論我將 UseLegacy 設為 True 或是 False,它的差別只有會不會出現說話以供辨識的提示而已;只要不說話了,SpeechRecognizer 就罷工休息了。
不過觀察了一下,每次罷工前,畫面總會出現錯誤代碼和訊息,大概就類似底下的:
- Error 3802: Client Side Error
- Error 3806: No Match
- Error 3807: RecognitionService Busy
- Error 3809: No Speech Input
有留下線索就好辦了!
如果是 Error 3802,SpeechRecognizer 會繼續工作,但如果是 Error 3806,SpeechRecognizer 就會去睡大頭覺了!
因此我試著在發生 Error3806 時,就重新利用 GetText() 叫醒 SpeechRecognizer。
另外當然一個需要再度呼叫 GetText() 的地方就是當語音已經辨識完成時。根據線上說明,當 SpeechRecognizer 進行完語音辨識時,會觸發 AfterGettingText 事件,而在 UseLegacy 設為 False 時,最後一部份完成辨識,在 AfterGettingText 中,還會把 partial 變數設為 False。所以在 AfterGettingText 中,可以利用 partial 是否為 False 來判斷它已辨識完成,我們就重新利用 GetText() 叫醒 SpeechRecognizer。
先來看看利用一個 Button、一個 Label 和一個本篇的主角 SpeechRecognizer 所構成的完整程序:
Error3806 在哪裡處理呢?
因為只有一個 Screen (Screen1) ,所以我們在 Screen1.ErrorOccurred 中放入檢查錯誤代碼,並重新呼叫 GetText() 的程序。
另一個讓語音辨識不中斷的關鍵則在 AfterGettingText 中:
注意上面積木塊中的第二個 if 積木,它用來在 partial 為 Fasle 時,重新呼叫 GetText() 的程序。
如果能處理 Error3806 及 partial 為 False 這兩點,並重新呼叫 GetText() ,就能讓 App Inventor 的語音辨識能夠一直維持上線狀態。
沒有留言:
張貼留言