var HogeVM = function () { this.enableSpeechButton = ko.observable(true); this.speechStatus = ko.observable("開始前"); this.alternatives = ko.observableArray(); // ---------- 音声解析処理 this.recognition = new webkitSpeechRecognition(); // 日本語を対象とする this.recognition.lang = "ja-JP"; // 継続的に入力を待つ this.recognition.continuous = true; // 不確かな情報も取得する this.recognition.interimResults = true; // 録音スタートイベント this.recognition.onstart = function () { this.speechStatus("録音スタート"); this.enableSpeechButton(false); this.alternatives([]); }.bind(this); // 録音終了イベント this.recognition.onend = function () { this.speechStatus("開始前"); this.enableSpeechButton(true); this.alternatives([]); }.bind(this); // 録音結果イベント this.recognition.onresult = function () { var _alternative = []; var speechs = event.results; for (var i = 0, speechsLength = speechs.length; i < speechsLength; i++) { var alternatives = speechs[i]; for (var n = 0, alternativesLength = alternatives.length; n < alternativesLength; n++) { _alternative.push(alternatives[n]); } } this.alternatives(_alternative); }.bind(this); // 録音開始処理 this.speechStart = function () { this.recognition.start(); }; // 録音停止処理 this.speechStop = function () { this.recognition.stop(); }; // ---------- 喋る処理 this.message = new SpeechSynthesisUtterance(); // ボリューム。0以上1以下の範囲で指定し、1が最大 this.message.volume = 1; // 発話速度を指定。3は3倍の速さで、0.5は半分の速さです。0.1未満、10以上はダメ this.message.rate = 1; // 話に対するピッチを指定。0〜2で指定できる this.message.pitch = 2; // 音声合成の言語を指定 this.message.lang = "ja-JP"; // 喋る処理終了イベント this.message.onend = function (event) { alert("say end!!"); }; // 喋る処理 this.say = function (sayValue) { // 喋る文字。最大長さは32767文字 this.message.text = sayValue; speechSynthesis.speak(this.message); }; }; ko.applyBindings(new HogeVM, document.getElementById('HogeVM'));
<div id="HogeVM"> <p data-bind="text: speechStatus"></p> <input type="button" data-bind="click: speechStart, enable: enableSpeechButton" value="録音開始"> <input type="button" data-bind="click: speechStop, disable: enableSpeechButton" value="録音停止"> <!-- ko foreach: alternatives --> <div><span data-bind="text: $data.transcript"></span> <input type="button" data-bind="click: $root.say.bind($root, $data.transcript)" value="読み上げる"> </div> <!-- /ko --> </div>