音声認識を取り入れたアプリを開発した時にいろいろ詰まったことがあったので備忘録。
何を使った??
まず音声認識をするのに使ったのはSpeechRecognizer!
Androidの音声認識をやるにはこれが基本みたいです。
やりたいこと
常に音声を拾いたい!拾ったら画面に認識した言葉を文字列として表示したい!
詰まったところ
ひとつめ
いざ音声認識をしてみたのですが、一回拾ったらその次の言葉を拾ってくれない。。
ええええ、なんで?となって調べまくりました。
連続して音声を拾うには、音声の取得が終わったところでまたSpeechRecognizer#startListening()
を呼べばいいそう!
音声認識した文字列を受け取った先でstartListeningするためにリスナーを用意しました。
エラーの時も処理を継続させたかったので、onError
時にもリスナーをよんでいます!
ざっくりですが、こんな感じ。
▼SpeechRecognizerのコールバック用クラス
class SpeechRecognizerListener(private val listener: SpeechResponseListener) : RecognitionListener {
// 音声結果を返却する
interface SpeechResponseListener {
fun onResultsResponse(speechText: String)
}
・・・略・・・
// ネットワークまたは、音声認識エラー
override fun onError(error: Int) {
listener.onResultsResponse("")
}
// 認識結果
override fun onResults(bundle: Bundle?) {
・・・略・・・
// 結果を返却する
if (speechText.isNullOrEmpty()) {
listener.onResultsResponse("")
} else {
listener.onResultsResponse(speechText)
}
}
}
▼リスナー先
override fun onResultsResponse(speechText: String) {
if (speechRecognizer != null) {
// SpeechRecognizerをdestroyする
speechRecognizer!!.destroy()
}
setupSpeechRecognizer()
setupRecognizerIntent()
speechRecognizer.startListening(intent)
muteBeepSoundOfRecorder(true, context)
}
二回目以降のstartListening()
を呼び出す前に、destroy()
しないとうまくいかないことがあるみたいなので、nullじゃなかったらdestroy
するようにしてます。
これで、連続して音声認識してくれることに成功しました。
ふたつめ
音声認識中になんだか音がピコンピコンうるさい。。
startListening
する時にmuteBeepSoundOfRecorder
というとこで音ミュートにしたりしてるのになぜ?!と詰まる。
▼実際のイメージ
鳴り続ける音。 pic.twitter.com/beI7ruMiY6
— tg_kondo (@KondoTg) October 20, 2020
これじゃぴこぴこうるさいですよね。
でもこれを追加しただけで音が鳴り止んだんです。
am.adjustStreamVolume(AudioManager.STREAM_SYSTEM, AudioManager.ADJUST_MUTE, 0)
AudioManager.STREAM_MUSIC
に対してだけしか操作してなかったんですけど、AudioManager.STREAM_SYSTEM
が必要だったんですねえ。笑
▼STREAM_SYSTEMを入れた後のイメージ
音が止んだ! pic.twitter.com/jNhp8t2cuz
— tg_kondo (@KondoTg) October 20, 2020
難しいなあ。