この章では、マイクの音声を認識し、文章に変換する機能を拡張機能として追加します。音声認識の部分には、ブラウザに内蔵されているWeb Speech APIというAPIを使います。(といっても、現在はChromeしか正式にサポートしていないので、この章ではChromeを使用してください)
SpeechとScratchをつなげるということで、拡張機能の名前はSpeech2Scratchです。
まず、node_modules以下にあるscratch-vm以下、src/extensionsの下にscratch3_speech2scratchというフォルダを作成し、その下にindex.jsというファイルを新しく作ります。

index.jsの内容は以下の通りです。
const ArgumentType = require('../../extension-support/argument-type');
const BlockType = require('../../extension-support/block-type');
const Cast = require('../../util/cast');
class Scratch3Speech2Scratch {
constructor (runtime) {
this.runtime = runtime;
this.speech = '';
}
getInfo () {
return {
id: 'speech2scratch',
name: 'Speech2Scratch',
blocks: [
{
opcode: 'startRecognition',
blockType: BlockType.COMMAND,
text: '音声認識開始'
},
{
opcode: 'getSpeech',
blockType: BlockType.REPORTER,
text: '音声'
}
],
menus: {
}
};
}
startRecognition () {
SpeechRecognition = webkitSpeechRecognition || SpeechRecognition;
const recognition = new SpeechRecognition();
recognition.onresult = (event) => {
this.speech = event.results[0][0].transcript;
}
recognition.start();
}
getSpeech() {
return this.speech;
}
}
module.exports = Scratch3Speech2Scratch;
前章同様、主要な箇所を説明していきますね。
constructor関数は、最初に一度だけ実行される関数です。マイクの音声を認識した結果を保存する変数this.speechの初期化をおこなっています。空の文字列’‘をセットしています。
getInfoでは追加するブロックの定義をおこなっています。
音声認識を開始するためのCOMMANDタイプのブロック「音声認識開始」と、マイクの音声を認識した結果を返すREPORTERタイプのブロック「音声」です。
{
opcode: 'startRecognition',
blockType: BlockType.COMMAND,
text: '音声認識開始'
},
{
opcode: 'getSpeech',
blockType: BlockType.REPORTER,
text: '音声'
},
「音声認識開始」ブロックの処理はstartRecognition関数で定義しています。
startRecognition () {
SpeechRecognition = webkitSpeechRecognition || SpeechRecognition;
const recognition = new SpeechRecognition();
recognition.onresult = (event) => {
this.speech = event.results[0][0].transcript;
}
recognition.start();
}
デフォルトでは使えないが、設定を有効にすれば使えるようになるFirefoxとChromeの両方に対応するために、 SpeechRecognition = webkitSpeechRecognition || SpeechRecognition; とします。
const recognition = new SpeechRecognition(); で初期化し、マイクの音声が途切れたときに実行されるrecognition.onresultイベントで、認識した結果であるevent.results[0][0].transcriptをthis.speechにセットしています。
これらを定義しておいた上で、recognition.start();で音声認識を開始しています。
「音声」ブロックの中身は、
getSpeech() {
return this.speech;
}
です。this.speechの内容を返しています。
次にsrc/extension-support/extension-manager.jsを編集して、scratch3_speech2scratchを追加します。

scratch-guiのコードを修正し、GPS2Scratch拡張機能を「拡張機能」のメニューに追加して選べるようにします。scratch-gui以下のsrc/lib/libraries/extensions/index.jsxの最後に以下を追加します。
{
name: 'Speech2Scratch',
extensionId: 'speech2scratch',
iconURL: speech2scratchImage,
insetIconURL: speech2scratchInsetImage,
featured: true,
},
index.jsxの最初の方には、以下のように画像のパスもimportしておきます。
import speech2scratchImage from './speech2scratch.png';
import speech2scratchInsetImage from './speech2scratch-small.png';
speech2scratch.png[サンプル]とspeech2scratch-small.png[サンプル]はsrc/lib/libraries/extensionsフォルダに置いておきます。
ターミナルより
npm start
を実行して、Scratch3を起動します。
ブラウザで http://localhost:8601/ にアクセスし、Speech2Scratch拡張機能を追加します。

「音声認識開始」ブロックを最初にクリックしたときには、ブラウザがマイクへのアクセスの許可を求めてくるので、「許可」のボタンをクリックします。

「音声」ブロックの横のチェックボックスをチェックしておくと、PCのマイクに向かって話した内容が「音声」にセットされるのがわかります。
Scratch公式の拡張機能の「音声合成」と「翻訳」のブロックとを組み合わせて、以下のようなスクリプトを作ると、簡単な翻訳機を作ることができます。

「スペース」キーをクリックして話すと、話した内容が5秒後に翻訳されます。その様子がこちらです。(音声付き)
Speech2Scratch拡張機能を追加した完成版は https://scratch3.netlify.app/ にて公開しています。