質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.03%

音声認識(Web Speech API)の音声認識停止ができない。

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,454

kimukimu009

score 11

下記のサンプルコードで、音声認識および停止のプログラムを作っていますが、音声認識の停止ができません。認識プログララムを、関数から呼び出す必要があり、引数によって、認識と停止を使い分けています。一度認識を呼び出すと、停止ができずに、認識を継続しておこなっているようです。強制的にでも、認識をストップし、停止を行うには、どうすればよろしいでしょうか?

■できること:音声の認識開始および、認識はできる。
■できないこと:音声の認識停止ができない。
(一度、recognition.start()を行っており、それを、永遠に関数で呼び出している為、どうも、recognition.stopを行っても、それが効いていないようです。)

■実行環境 https で動かしています。
■サンプルコード
<!DOCTYPE html>
<html>

<head>
<meta charset="UTF-8">
<title>test</title>

<script>
var flag_speech = 0;
var ketugou_part= "";

function vr_function(hantei) {

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 = "もう一度試してください共通";
};

if(hantei==1){    

recognition.onerror = function() {
document.getElementById('status').innerHTML = "エラー1";
if(flag_speech == 0)
vr_function(1);
};
recognition.onsoundend = function() {
document.getElementById('status').innerHTML = "停止中1";
vr_function(1);
};

flag_speech = 0;
document.getElementById('status').innerHTML = "start1";
recognition.start();
}

else if(hantei==0){
document.getElementById('status').innerHTML = "ストップ";
recognition.stop();
}

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;
document.forms['form2'].elements['text'].value= results[i][0].transcript ;
vr_function(1);

}
else
{
document.getElementById('result_text').innerHTML = "[途中経過] " + results[i][0].transcript;
flag_speech = 1;
}
}
}
}

</script>     

</head>

<body>

<input type="button" onClick="vr_function(1);" value="音声認識開始"><br>
<input type="button" onClick="vr_function(0);" value="音声認識を停止"><br>

■状態<br><textarea id="status" cols="100" rows="1"></textarea><br>
■認識された文字<br>
<textarea id="result_text" cols="100" rows="10">
</textarea>
<form name="form2"><input type="hidden" name="text" value=""></form>    
<br>

</body>

</html>

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

認識開始と認識停止処理のみ関数にして、その他は外に出せばいけるのでは?
下記サンプルは、音声入力をテキストエリアに表示するだけのサンプルです。

<body>
    <textarea id="textarea" rows=10 cols=80></textarea>
    <button id="button" onclick="toggleStartStop()"></button>
    <script>
        var recognizing; 
        window.SpeechRecognition = window.SpeechRecognition || webkitSpeechRecognition;
        var recognition = new webkitSpeechRecognition();
        recognition.continuous = true;
        recognition.lang = 'ja';
        recognition.interimResults = true;
        reset();
        recognition.onend = reset;
        recognition.onresult = function (event) {
            var results = event.results;
            for (var i = event.resultIndex; i < results.length; ++i) {
                if (results[i].isFinal) {
                    document.getElementById('textarea').value += results[i][0].transcript + "\n";
                }
            }
        }
        function reset() { 
            recognizing = false; 
            button.innerHTML = "Click to Speak"; 
        } 
        function toggleStartStop() { 
            if (recognizing) { 
                recognition.stop(); 
                reset(); 
            } 
            else { 
                recognition.start(); 
                recognizing = true; 
                button.innerHTML = "Click to Stop";
            }
        } 
    </script>

</body>


停止するまで、ずっと録音状態ってことですか・・
やったことないですが、無理やりやるとすれば以下でしょうか?
もっとスマートなやり方があるかもしれませんが、即席なのでご勘弁を。

<body>
    <textarea id="textarea" rows=10 cols=80></textarea>
    <button id="start" onclick="start()">Start</button>
    <button id="stop" onclick="stop()">Stop</button>
    <script>
        var recognizing;

        init();
        function init() {
            window.SpeechRecognition = window.SpeechRecognition || webkitSpeechRecognition;
            recognition = new webkitSpeechRecognition();
            recognition.continuous = true;
            recognition.lang = 'ja';
            recognition.interimResults = true;

            recognition.onend = reset;
            recognition.onresult = disp;

        }
        function disp(event) {
            var results = event.results;
            for (var i = event.resultIndex; i < results.length; ++i) {
                if (results[i].isFinal) {
                    document.getElementById('textarea').value += results[i][0].transcript + "\n";
                }
            }
        }
        function start() {
            init();
            recognition.start();
        }
        function stop() {
            recognition.onend = null;
            recognition.stop();
        }

        function reset() { 
            console.log("reset\n");
            init();
            recognition.start();
        } 
        recognition.onerror = function(event)  {
            console.log('音声認識エラーが検出されました:' + event.error);
        }
    </script>
</body>

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/15 12:50

    ありがとうございます!感謝いたします。
    やりたいことが、実現できています。

    最後にひとつ教えてください。
    このコードの中で、再生をしつづける所のポイントは、どこにあるのでしょうか?

    よろしくお願いいたします。

    キャンセル

  • 2018/10/15 14:40

    recognition.onend = reset; ← 終了時の処理をreset関数にセット
    reset関数内で、再度webkitSpeechRecognitionクラスを作成して、start()を開始
    stop時には、recognition.onend = null;で終了時の処理をクリアしてstop()しています。
    あくまで、無理やりやってますので、これが正規の手順かどうかわかりません。

    キャンセル

  • 2018/10/15 15:27

    ありがとうございます。
    大変、勉強になりました。今後共、よろしくお願いいたします。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.03%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる