背景
前回記事のGoogle Apps ScriptによるクイズWebアプリを作って英語学習するのアプリを自分で使っていて、以下の機能があると、なお良いと思った。
- 答えの読み上げ機能(英単語の場合、iPhoneだと長タッチで辞典開いて発音記号を見れるが、その時間を短縮する)
- 問題番号を表示する機能(問題が本の何頁にあるのか、逆引きするのにひと手間かかる)
- これまでの出題回数を表示する機能(問題数が増えてくると、過去出題された累計が気になる)
- 難しい問題のチェック機能(問題のチェックはスプレッドシートにアクセスすれば可能だが、アプリからワンクリックでチェックできるようにしたい)
以前の記事では、目標をクイズWebアプリ作成として、比較的汎用的なアプリとしてリファクタリング・解説しました。
ですが、上で述べた要求機能がどんどん出てきて、このアプリを、より自身の英語学習目的に特化したアプリにしたいという目標ができました。
本記事以降、本アプリの名前を、TOEIC金フレを更に学ぶための**"英語学習Webアプリ"**と改めます。
目的
以下4つの機能追加の結果報告・苦労した点の情報共有を、本記事の目的とします。
また今後、GASによる英語学習Webアプリをコーディングされる方のために、この資料が参考になればと思います。
- 答え表示時、Web Speech APIを用いた英単語の読み上げ機能追加する。
- 出題時、問題番号を表示する機能追加する。
- 出題時、これまでの出題回数を表示する機能を追加する。(前回の記事の通り、最大出題回数を満たした問題は出題されない)
- 一定回数以上出題された問題の答え表示時、「問題チェック」ボタンを表示し、押下でスプレッドシートを着色する機能追加する。(チェックされた問題は、3の条件を満たした問題であっても出題される)
結論
できました!
PC実行風景
— すいばり@'18年度1戦0勝1敗 (@Suibari_cha) 2018年5月7日
想像より流暢に読み上げてくれる
(個人的にはiOS safariの声の方が好み) pic.twitter.com/i4uxcpsS9H
内容
全体コードについては、GitHubを参照ください!(2020/8/15追記)
GiHub: suibari/QuizVocabulary
以下、目的で述べたWeb Speech API利用および問題チェック機能など、各モジュールについて解説します。
-1. Web Speech API
ブラウザのテキスト読み上げ機能を使っています。
よって、動作可否や性能(声質)などはブラウザに依存しますが、私の環境("Win10 Chrome"および"iOS11.3 Safari")では、十分流暢に発音してくれると感じました。
たった数文でこんな手軽に喋らせられることに感動。
function speechTextInLang (text, lang) {
var speech = new SpeechSynthesisUtterance();
var voices = window.speechSynthesis.getVoices();
speech.text = text;
speech.lang = lang;
// 声質の設定
for (var i = 0; i < voices.length; i++) {
if (voices[i].lang == lang) speech.voice = voices[i];
}
// 喋らせる
speechSynthesis.speak(speech);
};
-1.1 声質の設定について
声質の設定は以下部分で行っています。
アルゴリズムについては後述します。このアルゴリズムがミソだと思ってます。
var speech = new SpeechSynthesisUtterance(); // インスタンス生成
var voices = window.speechSynthesis.getVoices(); // ブラウザから声質配列voicesを取得
// voicesを掃引し、langプロパティが引数lang("US-en")と等しい声を選び、
// speech.voiceプロパティにセットする
for (var i = 0; i < voices.length; i++) {
if (voices[i].lang == lang) speech.voice = voices[i];
}
声質の配列voices
は、ブラウザ毎に約30前後実装されており、開発者が任意の声質を選択して発声させる仕組みです。
なので、プリセットの声質(日本語)のまま英語を喋らせてみたらひどい棒読みだったというのは有り得ます。
しかも、voices
はブラウザごとにプロパティの名前が全く異なるので、マルチデバイスを意識する場合、アプリ側で、voices
を識別をしてから発声させなければならないといえます。
参考文献より、以下引用します。
声質の種類を指定するには、uttrインスタンスの
voice
属性にvoice
オブジェクトをセットする必要があります。voice
オブジェクトは、speechSynthesis.getVoices()
を実行することで、利用環境で使用可能なvoice
オブジェクトを配列形式でまとめて取得することができます。
参考文献: Web Speech APIの実装 いろいろな種類の声質で再生する より
したがって、上のコードではspeechSynthesis.getVoices()
で得た声質配列voices
のうち、"US-en"
の発音に向いたvoiceを、配列をなめて選択しています。
-2. 問題チェック機能
「問題チェック」ボタンの押下時、スプレッドシートの該当する問題を着色します。
コードは以下の通り。
<script>
function onHighlightBtnClick() {
// html読み取り
var answer = document.getElementById("answer");
var btn_hlt = document.getElementById("btn_hlt");
google.script.run.highlightSpecificQuiz(answer.innerHTML);
btn_hlt.innerHTML = "チェック済み";
}
</script>
function highlightSpecificQuiz(ans) {
// スプレッドシート処理
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('List');
// 行番号探索
var r = searchRowInColumnByString(ans, "D");
// 問題番号セルを着色
sheet.getRange("A" + r).setBackground('#ffff00');
}
考察
- 前回の記事同様、隙間時間での英語頻出フレーズ学習という点で、高い学習効果があると思っています。**既に500フレーズ近く覚えられました。**おすすめです!
- このように、自分の学習目的(開発以外)で何らかのアプリを開発する場合、そのアプリのデバッグ・検証を行っていく過程で、(いやでも)本来目的の学習が進んでいくというメリットがあることに気づきました。
- ちなみに、肝心のTOEICは7月下旬受験します。6月まで金フレ、7月は公式問題集の予定です。結果はTwiiterで。
-
テキスト読み上げ関数を見ていただくと分かるように、呼び出されるたびに
SpeechSynthesisUtteranceのインスタンス
を生成してます。本来、HTML読み込み時に一度生成するだけで良いと思ってます。処理が遅くなるわけでもないので、ほったらかしにしてます。うまいやり方あるのかしら。