LoginSignup
9
8

More than 3 years have passed since last update.

NoodlでWeb Speech API Speech Recognitionを使う!Noodl Javascriptノードの使い方も解説

Last updated at Posted at 2020-01-01

※この記事は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

サンプルページはコチラ
※micro:bitは抜いてます。

サンプルの使い方

1. Noodlのプロジェクトをクローンする

ここからクローンし、Noodl2.0で読み込んでください。

2. chromeをブラウザから開く

スクリーンショット 2020-01-01 22.09.56.png
右上のブラウザアイコン→URLをクリックします。

スクリーンショット 2020-01-01 22.10.12.png
URLの「192.168.xxx.xxx」を「localhost」に変更する。
※ブラウザの制限で、マイク機能はlocalhostかhttpsでないと動かないためです。サーバーにデプロイすることでも解消されます。

3. ラーメン画像をクリックし、マイクを許可

ラーメンタップで音声認識が開始します。

NoodlのJavascriptノードの解説

Noodl1.3のJavascriptノードと少し使用が変わっているようです。
基本的な使い方の説明と、NoodlでJavascriptノードで非同期通信するときのコツを記述します。

inputsとoutputs

inputs: 任意の入力ポートを作ることができる。
outputs: 任意の出力ポートを作ることができる。

書き方
inputの名前:'データ型'
利用可能な型:'number', 'string', 'boolean', 'color', 'signal', 'collection'

mySignal:function

特定のシグナルが来た場合に実行したいときに使用します。
例えば、タップしたら実行するなど。


任意のinput名その1boolean)】:function{
//実行したい処理
},
任意のinput名その2boolean)】: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のみなのが不便ですが、今後、他のブラウザにも実装されることを祈ります...!

9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8