SpeechRecognition/Synthesisでかんたんオウム返し
SpeechRecognition/Synthesisとは!?
SpeechRecognitioは、音声認識APIです。(ブラウザに向かって発した声を文字に変換します)
SpeechRecognition
SpeechSynthesisは、音声読み上げAPIです。(文字を音声として自動で読み上げます)
SpeechSynthesis
今回はこの2つのAPIを使い、オウム返しシステムを作ってみます。
プロジェクトを用意する
次の様にプロジェクトを作ります。
MyProject01/
├ index.html (プログラムを起動するファイルです)
├ main.js (メインのプログラムを記述するファイルです)
HTMLファイルを用意する
では、作っていきましょう。
HTMLファイルを用意して、下記コードを記述します。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<script src="./main.js" defer></script>
</head>
<body>
<button id="btnStart">開始</button>
<button id="btnStop">停止</button>
<ul id="txtResult"></ul>
</body>
</html>
HTMLには開始ボタンと停止ボタン、そして音声認識した内容を表示するエリアを用意しておきます。
JavaScriptファイルを用意する
次はメインのプログラムです。
ここからは、次の順番で解説をしていきますね。
- 音声読み上げAPIをインスタンス化する関数を用意する
- 音声認識APIをインスタンス化する関数を用意する
- 開始ボタン、停止ボタンで音声認識を開始する
1, 音声読み上げAPIをインスタンス化する関数を用意する
"SpeechSynthesisUtterrance"オブジェクトは、発話に関連するオブジェクトです。
各パラメータには、声質、音量、速度、音程を指定する事が出来ます。
このオブジェクトを返す関数として、"readySpeak関数"を用意します。
同時に、発話させる命令をまとめた関数"startSpeak関数"も用意しておきます。
function readySpeak(callback){
const utter = new SpeechSynthesisUtterance();
const voices = window.speechSynthesis.getVoices();
utter.voice = voices[7]; // 7:Google 日本人 ja-JP
utter.volume = 1.0; // 音量 min 0 ~ max 1
utter.rate = 0.5; // 速度 min 0.1 ~ max 10
utter.pitch = 1.0; // 音程 min 0 ~ max 2
utter.lang = "ja-JP";
utter.text = "何か言いましたか!?";
utter.onend = callback;// Callback
return utter;
}
function startSpeak(utter, text){
utter.text = text;
speechSynthesis.speak(utter);
}
2, 音声認識APIをインスタンス化する関数を用意する
"webkitSpeechRecognition"オブジェクトを返す、"readyRecognition関数"を用意します。
このオブジェクトのイベント"onresult"では音声認識の結果を取得する事ができます。
"onerror"イベントでは、エラーハンドリングを行います。(エラー時に音声認識を再始動させます)
function readyRecognition(callback){
const rec = new webkitSpeechRecognition();
rec.continuous = true;
rec.interimResults = false;
rec.lang = "ja-JP";
rec.onresult = (e)=>{
for(let result of e.results){
if(!result.isFinal) continue;
rec.stop();
callback(result[0].transcript);// Callback
}
}
rec.onerror = (e)=>{
if(e.error !== "no-speech") return;
setTimeout(()=>{rec.start();}, 500);
}
return rec;
}
3, 開始ボタン、停止ボタンで音声認識を開始する
最後は簡単です。
HTMLに用意しておいた2つのボタンのクリックイベントを実装します。
document.getElementById("btnStart").onclick = ()=>{
rec.start();// 音声認識開始
}
document.getElementById("btnStop").onclick = ()=>{
rec.stop();// 音声認識停止
}
そして、認識結果である文字列を表示する"addText関数"を実装しています。
function addText(str){
const elem = document.createElement("li");
elem.innerHTML = str;
document.getElementById("txtResult").appendChild(elem);
}
全体のコード
最後に、全体のコードを載せておきます。
window.onload = ()=>{
const utter = readySpeak((e)=>{
console.log("Time:" + e.elapsedTime);
setTimeout(()=>{rec.start();}, 500);// 音声読み上げが終了したら音声認識を起動する
});
const rec = readyRecognition((text)=>{
startSpeak(utter, text);// 音声認識が完了したら、音声読み上げを実行する
addText(text);// 認識結果をHTMLに表示する
});
document.getElementById("btnStart").onclick = ()=>{
rec.start();// 音声認識開始
}
document.getElementById("btnStop").onclick = ()=>{
rec.stop();// 音声認識停止
}
}
function readyRecognition(callback){
const rec = new webkitSpeechRecognition();
rec.continuous = true;
rec.interimResults = false;
rec.lang = "ja-JP";
rec.onresult = (e)=>{
for(let result of e.results){
if(!result.isFinal) continue;
rec.stop();
callback(result[0].transcript);// Callback
}
}
rec.onerror = (e)=>{
if(e.error !== "no-speech") return;
setTimeout(()=>{rec.start();}, 500);
}
return rec;
}
function readySpeak(callback){
const utter = new SpeechSynthesisUtterance();
const voices = window.speechSynthesis.getVoices();
utter.voice = voices[7]; // 7:Google 日本人 ja-JP
utter.volume = 1.0; // 音量 min 0 ~ max 1
utter.rate = 0.5; // 速度 min 0.1 ~ max 10
utter.pitch = 1.0; // 音程 min 0 ~ max 2
utter.lang = "ja-JP";
utter.text = "何か言いましたか!?";
utter.onend = callback;// Callback
return utter;
}
function startSpeak(utter, text){
utter.text = text;
speechSynthesis.speak(utter);
}
function addText(str){
const elem = document.createElement("li");
elem.innerHTML = str;
document.getElementById("txtResult").appendChild(elem);
}
なんと、これだけでオウム返しシステムが出来てしまいます。(やりました!!)
最後に
今回は、喋った内容をそのまま返すオウム返しシステムを作ってみました。
捉えた文字の特定の言葉にだけ反応させたりすると、面白い物が作れそうな気がしてきます。
ここまで読んでいただき有難うございました。
Discussion