2021年07月31日 更新
どうも、クラゲです。
Web Speech APIを使って途切れない音声認識を行います!
[TOC]
実際のデモが体験できるページはこちら
https://monomonotech.jp/kurage/assets/scripts/iot/webspeechapi_voice_recognition
この「途切れない」というのが今回のミソです。Web Speech APIはJavaScriptで非常に簡単にプログラミングできますが、数秒経つと音声認識が停止してしまいます。そうなると手動で再開しなければいけなかったり、再開の度にマイクの使用許可を聞かれて毎回タップするのが面倒です。
そんな面倒な手間を解放し、途切れずに長時間、音声認識を続ける技を紹介します!
ローカルやHTTPサーバーだと動作しなかったり、マイクの使用許可を毎回許可する必要があり実用的ではありません。
音声認識終了後、停止後、エラー時などに関数を再び呼びますが、そこにコツがあります。
たったこれだけのhtmlファイルで音声認識が出来てしまいます!
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Web Speech API</title>
<script>
window.SpeechRecognition = window.SpeechRecognition || webkitSpeechRecognition;
var recognition = new webkitSpeechRecognition();
recognition.lang = 'ja';
recognition.onresult = function(event){
var results = event.results;
for (var i = event.resultIndex; i<results.length; i++)
document.getElementById('result_text').innerHTML = results[i][0].transcript;
}
</script>
</head>
<body>
<textarea id="result_text" cols="100" rows="10">
</textarea>
<br>
<input type="button" onClick="recognition.start();" value="音認開始">
</body>
</html>
HTTPSサーバーにファイルを置いて、ブラウザはChromeで動作確認してください。
ローカル上やHTTPサーバーで起動してもダメで、HTTPSサーバー上で起動する必要があります。
サーバー持ってない人は、後で紹介する無料のホスティングサービスがありますのでそちらを活用してみてください。
起動がうまくいくと以下のようなアラートが表示されます。
許可を選ばないと音声認識されません。
全く認識されない場合は、マイクの設定の問題です。
chromeの設定
> プライバシーとセキュリティ―
> サイトの設定
> マイク
で適切なデバイスに変更してください。
サーバーを持っていない人はこちらを活用してみてください。
https://app.netlify.com/drop
24時間で消えますが、サインインしなくてもいきなりサーバーにアップロードすることが出来ます。
ローカルPCにてフォルダを新規作成します。フォルダ名は何でもOKです。その中にindex.html
を新規作成して先程のコードをコピペします。
そのフォルダをドラッグ&ドロップするだけでできます。
単体ファイルじゃなくて、フォルダに入れてUPするのがポイントです。たまに失敗するときがありますが、何度かドラッグ&ドロップしてみて下さい。
先ほどのシンプルなコードだと物足りないので、肉付けします。
recognition.interimResults = true
で 変換途中も認識
isFinal
を使えば変換終了したかを判定できる
recognition.continuous = true
で連続で音声認識できる。
onsoundstart
, onsoundend
, onerror
を用いることにより状態が分かる。
これらの機能を追加したソースです。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Web Speech API</title>
<script>
window.SpeechRecognition = window.SpeechRecognition || webkitSpeechRecognition;
var recognition = new webkitSpeechRecognition();
recognition.lang = 'ja';
recognition.interimResults = true;
recognition.continuous = true;
recognition.onsoundstart = function(){
document.getElementById('status').innerHTML = "認識中";
};
recognition.onnomatch = function(){
document.getElementById('status').innerHTML = "もう一度試してください";
};
recognition.onerror= function(){
document.getElementById('status').innerHTML = "エラー";
};
recognition.onsoundend = function(){
document.getElementById('status').innerHTML = "停止中";
};
recognition.onresult = function(event){
var results = event.results;
for (var i = event.resultIndex; i<results.length; i++){
if(results[i].isFinal)
document.getElementById('result_text').innerHTML = results[i][0].transcript;
else
document.getElementById('result_text').innerHTML = "[途中経過] "+ results[i][0].transcript;
}
}
</script>
</head>
<body>
<textarea id="result_text" cols="100" rows="10">
</textarea>
<br>
<textarea id="status" cols="100" rows="1">
</textarea>
<br>
<input type="button" onClick="recognition.start();" value="音認開始">
</body>
</html>
ずっとしゃべり続けていると、音声認識も連続でできるようになったと思います。
しかし、無音で数秒経過すると、音声認識ができなくなってしまいます。
次にこれを攻略します。
まず、先ほどのscript全体を関数化します。
音声認識停止もしくは音声認識が完了になったら全体関数を呼ぶようにします。
エラーの場合は、flag_speech
というフラグを用意し、認識途中でない場合のみ全体関数を呼びます。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Web Speech API</title>
<script>
var flag_speech = 0;
function vr_function() {
window.SpeechRecognition = window.SpeechRecognition || webkitSpeechRecognition;
var recognition = new webkitSpeechRecognition();
recognition.lang = 'ja';
recognition.interimResults = true;
recognition.continuous = true;
recognition.onsoundstart = function() {
document.getElementById('status').innerHTML = "認識中";
};
recognition.onnomatch = function() {
document.getElementById('status').innerHTML = "もう一度試してください";
};
recognition.onerror = function() {
document.getElementById('status').innerHTML = "エラー";
if(flag_speech == 0)
vr_function();
};
recognition.onsoundend = function() {
document.getElementById('status').innerHTML = "停止中";
vr_function();
};
recognition.onresult = function(event) {
var results = event.results;
for (var i = event.resultIndex; i < results.length; i++) {
if (results[i].isFinal)
{
document.getElementById('result_text').innerHTML = results[i][0].transcript;
vr_function();
}
else
{
document.getElementById('result_text').innerHTML = "[途中経過] " + results[i][0].transcript;
flag_speech = 1;
}
}
}
flag_speech = 0;
document.getElementById('status').innerHTML = "start";
recognition.start();
}
</script>
</head>
<body>
<textarea id="result_text" cols="100" rows="10">
</textarea>
<br>
<textarea id="status" cols="100" rows="1">
</textarea>
<br>
<input type="button" onClick="vr_function();" value="音認開始">
</body>
</html>
これで途切れることなく使えるようになりました!
以上、Web Speech APIを使った途切れない音声認識でした。