※この記事はNoodl2.0を使用しています
NoodlでWeb Speech API Speech Recognitionを使う方法です。
音声認識を使うとなると、バックエンド側の開発が必要となり大変ですよね。
Chromeのブラウザのみ対応になりますが、Web Speech API Speech Recognitionを使うと
数行のJavascriptで簡単にマイクから拾った音声をテキストにすることができます!
参考にした記事
Web Speech API Speech Recognitionについて、詳細はこちら
Webページでブラウザの音声認識機能を使おう - Web Speech API Speech Recognition
あけおめmicrobit!!
— 年越しはりねずみ麺 (@hedgehog_noodl) December 31, 2019
無音だけど音声認識してる#Noodl #microbit #年越しNoodl pic.twitter.com/nhiWXMCcbp
サンプルページはコチラ
※micro:bitは抜いてます。
サンプルの使い方
1. Noodlのプロジェクトをクローンする
2. chromeをブラウザから開く
右上のブラウザアイコン→URLをクリックします。 URLの「192.168.xxx.xxx」を「localhost」に変更する。 ※ブラウザの制限で、マイク機能はlocalhostかhttpsでないと動かないためです。[サーバーにデプロイ](https://qiita.com/kmaepu/items/d59fe69d1c5e3f591504)することでも解消されます。3. ラーメン画像をクリックし、マイクを許可
ラーメンタップで音声認識が開始します。
NoodlのJavascriptノードの解説
Noodl1.3のJavascriptノードと少し使用が変わっているようです。
基本的な使い方の説明と、NoodlでJavascriptノードで非同期通信するときのコツを記述します。
inputsとoutputs
inputs: 任意の入力ポートを作ることができる。
outputs: 任意の出力ポートを作ることができる。
書き方
inputの名前:'データ型'
利用可能な型:'number', 'string', 'boolean', 'color', 'signal', 'collection'
mySignal:function
特定のシグナルが来た場合に実行したいときに使用します。
例えば、タップしたら実行するなど。
【任意のinput名その1(boolean)】:function{
//実行したい処理
},
【任意のinput名その2(boolean)】:function{
//実行したい処理
}
このように、複数追加もできるようです。
Noodl1.3ではこのような処理はif文で書いていました。2.0のほうがスッキリかけそうですね。
change:function
inputの値のどれかが変更されたときに実行される。
このプロジェクトのJavascriptノードの中身
サンプルでは、ラーメンをタップしたときにmySignalにtrueのシグナルを送り、音声認識を実行させています。
define({
// The input ports of the Javascript node, name of input and type
inputs:{
// ExampleInput:'number',
// Available types are 'number', 'string', 'boolean', 'color' and 'signal',
mySignal:'signal'
},
// The output ports of the Javascript node, name of output and type
outputs:{
// ExampleOutput:'string',
text: "string",
received: "boolean",
finalTextReceived:"boolean"
},
// All signal inputs need their own function with the corresponding name that
// will be run when a signal is received on the input.
mySignal:function(inputs,outputs) {
// ...
outputs.received = false;
outputs.finalTextReceived = false;
outputs.received = false;
SpeechRecognition = webkitSpeechRecognition || SpeechRecognition;
const recognition = new SpeechRecognition();
recognition.interimResults = true;
recognition.onresult = (event) => {
outputs.text = event.results[0][0].transcript;
this.flagOutputDirty("text");
this.sendSignalOnOutput("received");
console.log(event.results[0].isFinal);
outputs.finalTextReceived = (event.results[0].isFinal) ? true:false;
this.flagOutputDirty("finalTextReceived");
}
recognition.start();
},
// This function will be called when any of the inputs have changed
change:function(inputs,outputs) {
// ...
}
})
})
Javascriptノードで非同期通信をするときのコツ
Javascriptノード内で非同期通信をすると、
レスポンスが返ってきているのにoutputsが変更されない!という問題に遭遇します。
基本的にNoodlはinputsに変更があったときに中の関数を実行するため、
実行後にレスポンスが返ってきても、きちんとトリガーを作らない限りoutputsに反映されません。
こうした問題を解決するため、JavascriptノードにはいくつかのAPIが用意されています。
this.flagOutputDirty("変更を反映させたいoutputの名前")
inputsの変更以外をトリガーに、outputsを変更させるときに使用します。
このサンプルでは、音声認識のレスポンスが返ってきたときに、認識結果の文字列を"text"の出力に反映させています。
this.sendSignalOnOutput("任意のoutputの名前(boolean)")
素早くfalseからtrueへの往復を繰り返すブーリアンの信号を発信します。
このサンプルでは、音声認識のレスポンスが返ってきたときに信号を送信し、
音声認識中のアニメーション(ラーメンの拡縮)を止めるトリガーにしています。
まとめ
Javascript数行で音声認識ができました!すごい!
対応ブラウザがchromeのみなのが不便ですが、今後、他のブラウザにも実装されることを祈ります...!