LoginSignup
1
1

More than 1 year has passed since last update.

Web APIを使って、特定の音声に対して返答するWebアプリの作成

Posted at

背景

ひとり暮らししていると
家に帰って「ただいま」 といっても返答がない

 悲しい…

そんなことありますよね。
この悲しさを少しでも緩和してくれるアプリを作成しました。

制作物

このCodepenを参考にしました。

こちらのCodePenでは音声の認識と出力が別になっています。

今回は、
Web APIを使用し、特定の入力音声に応じて音声が出力されるように作成しました。

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>あいさつ返答</title>
</head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
<body>

    <h1>あいさつ返答アプリ</h1>
    <div id="app">
        <p>
            音声読み込み
            <button @click="listen">{{ recogButton }}</button> {{ result }}
        </p>
        <p>
            発話させる(日本語)<br>
            <input v-model="message" /> <button @click="say">しゃべって!</button>
        </p>
    </div>
    <script>
        //音声認識
        const app = new Vue({
            el: '#app',
            data: {
                recogButton: 'スタート!',
                recog: null,
                result: '',
                speech: null,
                message: '',
            },
            mounted() {
                // 音声認識の準備
                const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition || window.mozSpeechRecognition || window.msSpeechRecognition || null;
                this.recog = new SpeechRecognition();
                this.recog.lang = 'ja-JP';
                this.recog.interimResults = false;
                this.recog.continuous = false;

                // 音声認識が開始されたら
                this.recog.onstart = () => {
                    this.result = '';
                    this.recogButton = '聴き取り中…';
                };

                // 音声を認識できたら
                this.recog.onresult = (event) => {
                    // 認識されしだい、this.resultにその文字をいれる
                    // Vueなので、文字をいれただけで画面表示も更新される
                    this.result = event.results[0][0].transcript;
                    //修正箇所
                    if (this.result == 'おはよう' || this.result == 'おはようございます') this.speech.text = this.result;
                    else if (this.result == 'いただきます') this.speech.text = '召し上がれ';
                    else if (this.result == 'ごちそうさま' || this.result == 'ごちそうさまでした') this.speech.text = 'お粗末さまでした';
                    else if (this.result == 'ただいま') this.speech.text = 'おかえり';
                    else if (this.result == 'ただいま帰りました') this.speech.text = 'おかえりなさいませ、ご主人様';
                    else if (this.result == 'ありがとう' || this.result == 'ありがとうございます') this.speech.text = 'どういたしまして';
                    else if (this.result == 'ごめんなさい' || this.result == 'すいません') this.speech.text = '気にしないでね';
                    else if (this.result == 'こんにちは') this.speech.text = this.result;
                    else if (this.result == 'はじめまして') this.speech.text = this.result;
                    else if (this.result == 'お疲れ様' || this.result == 'お疲れ様でした' || this.result == 'お疲れ') this.speech.text = this.result;
                    else this.speech.text = "すみません、よくわかりません";
                    return new Promise((res) => {
                        this.speech.onend = () => res();
                        speechSynthesis.speak(this.speech);
                    });
                };

                // 音声認識が終了したら
                this.recog.onspeechend = () => {
                    this.recog.stop();
                    this.recogButton = '再開';
                };

                // 認識できなかったら
                this.recog.onerror = () => {
                    this.result = '(認識できませんでした)';
                    this.recog.stop();
                    this.recogButton = '再開';
                };

                // 発話の準備
                this.speech = new window.SpeechSynthesisUtterance();
                this.speech.lang = 'ja-JP';
                // または、ブラウザが対応している言語のうちja-JPな最初のボイスを使う
                window.speechSynthesis.onvoiceschanged = () => {
                    const voices = window.speechSynthesis.getVoices();
                    this.speech.voice = voices.find(voice => voice.lang == 'ja-JP');
                    console.log(this.speech.voice);
                };
            },
            methods: {
                // 認識(聞き取り)
                listen() {
                    this.recog.start();
                },
                // なんかしゃべる(いちおう非同期対応)
                async say() {
                    return new Promise((res) => {
                        this.speech.text = this.message;
                        this.speech.onend = () => res();
                        speechSynthesis.speak(this.speech);
                    });
                },
            },
        });
    </script>
</body>

</html>

完成したコードペン

変更点とコード解説

this.recog.onresultメソッド内のthis.resultに入力された音声が格納されるため
そこをif文で条件分岐させました。

返答させたい文章がthis.speech.text変数に格納されています。

もっといろんな音声に対応させたい場合はforkして編集してみてください。

Tips

■CodePenのプラグイン
 各言語の右側に歯車マークがあります。
 そこでプラグインの設定や確認ができます。
 CodePen外で使用する際は、適宜挿入が必要でした。
■Web API
・これいれるだけでバイブレーションが使えます。
 何かに使用できそうです...
window.navigator.vibrate(2000);

・公式ドキュメント > インターフェース
 大量にありますが、いずれ全てに目を通したいと思います。

1
1
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
1
1