17
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

TOIEC頻出フレーズ+読み上げ機能(WebSpeechAPI)による”英語学習Webアプリ”を作った

Last updated at Posted at 2018-05-08

背景

 前回記事のGoogle Apps ScriptによるクイズWebアプリを作って英語学習するのアプリを自分で使っていて、以下の機能があると、なお良いと思った。

  • 答えの読み上げ機能(英単語の場合、iPhoneだと長タッチで辞典開いて発音記号を見れるが、その時間を短縮する)
  • 問題番号を表示する機能(問題が本の何頁にあるのか、逆引きするのにひと手間かかる)
  • これまでの出題回数を表示する機能(問題数が増えてくると、過去出題された累計が気になる)
  • 難しい問題のチェック機能(問題のチェックはスプレッドシートにアクセスすれば可能だが、アプリからワンクリックでチェックできるようにしたい)

 以前の記事では、目標をクイズWebアプリ作成として、比較的汎用的なアプリとしてリファクタリング・解説しました。
 

 ですが、上で述べた要求機能がどんどん出てきて、このアプリを、より自身の英語学習目的に特化したアプリにしたいという目標ができました。
 本記事以降、本アプリの名前を、TOEIC金フレを更に学ぶための**"英語学習Webアプリ"**と改めます。

目的

 以下4つの機能追加の結果報告・苦労した点の情報共有を、本記事の目的とします。
 また今後、GASによる英語学習Webアプリをコーディングされる方のために、この資料が参考になればと思います。

  1. 答え表示時、Web Speech APIを用いた英単語の読み上げ機能追加する。
  2. 出題時、問題番号を表示する機能追加する。
  3. 出題時、これまでの出題回数を表示する機能を追加する。(前回の記事の通り、最大出題回数を満たした問題は出題されない)
  4. 一定回数以上出題された問題の答え表示時、「問題チェック」ボタンを表示し、押下でスプレッドシートを着色する機能追加する。(チェックされた問題は、3の条件を満たした問題であっても出題される)

結論

 できました!

内容

 全体コードについては、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読み込み時に一度生成するだけで良いと思ってます。処理が遅くなるわけでもないので、ほったらかしにしてます。うまいやり方あるのかしら。

参考文献

  1. Web Speech Synthesis API(音声合成API)で遊んでみた
  2. Web Speech APIの実装 前編 Speech Synthesis API
17
23
2

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
17
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?