Railsブラウザに話させる~読み上げ機能を追加~

# Railsに読み上げ機能を実装する

仕組み：`Web Speech Synthesis API` をRailsから使う

・紹介
　　ーいわゆる音声合成APIだそうです
　　ー探してたんだけど、みんな有料だったり音質悪かったり・・・しかし、このAPIは音質も良いし、漢字も読めます、そしてもちろん無料！

追記：オフラインでも動作可能！！

・以下リンク
　　ー[日本語](http://qiita.com/kyota/items/da530ad22733b644518a)
　　ー[英語](https://developers.google.com/web/updates/2014/01/Web-apps-that-talk-Introduction-to-the-Speech-Synthesis-API)

・導入
　　ー特にない
　　ーしかも無料

*　素晴らしい！！*
## 使ってみる

 ・まずは基本から

```XX.erb

<%=javascript_tag do%>

var msg = new SpeechSynthesisUtterance();
var voices = window.speechSynthesis.getVoices();
msg.voice = voices[10]; //[7]が日本語
msg.voiceURI = 'native';
msg.volume = 1; // 0 to 1
msg.rate = 1; // 0.1 to 10
msg.pitch = 2; //0 to 2
msg.text = 'Hello World';
msg.lang = 'en-US';

msg.onend = function(e) {
  console.log('Finished in ' + event.elapsedTime + ' seconds.');
};

speechSynthesis.speak(msg);

<%end%>
```

・応用

こうすれば、コントローラで値を渡して読み上げてあげることが可能

```XX.erb


<%= javascript_tag do %>
    <%@speak.each do |speak|%>
    var speak_value = "<%= speak.question %>";
    var msg = new SpeechSynthesisUtterance();
    var voices = window.speechSynthesis.getVoices();
    msg.voice = voices[7]; // Note: some voices don't support altering params
    msg.voiceURI = 'native';
    msg.volume = 1; // 0 to 1
    msg.rate = 0.8; // 0.1 to 10
    msg.pitch = 1; //0 to 2
    msg.text = speak_value;
    msg.lang = 'ja-JP';

    msg.onend = function(e) {
    console.log('Finished in ' + event.elapsedTime + ' seconds.');
    };

    speechSynthesis.speak(msg);
    <%end%>
<%end%>
```
下記の例では、`find`メソッドより、ある一つの、オブジェクトのページにアクセスされたら、読み上げるようにしている。

```XX.erb

<%= javascript_tag do %>
        var count = "<%= @word.question %>";
        var msg = new SpeechSynthesisUtterance();
        var voices = window.speechSynthesis.getVoices();
        msg.voice = voices[7]; // Note: some voices don't support altering params
        msg.voiceURI = 'native';
        msg.volume = 1; // 0 to 1
        msg.rate = 0.8; // 0.1 to 10
        msg.pitch = 1; //0 to 2
        msg.text = count;
        msg.lang = 'ja-JP';

        msg.onend = function(e) {
        console.log('Finished in ' + event.elapsedTime + ' seconds.');
        };

        speechSynthesis.speak(msg);
<%end%>

```
## 追記 2016年12月24日
heroku にデプロイして、iphoneからアクセスすると音が再生されなかった

その後、おそらくrailsとの相性があまり良くないとおもい、`js`に値をを直接渡そうと`gon`でやってみたがやはりうまくいかず。
結局、htmlの`hiden_field`に値を保持させjsで値を拾うようにした。
ただし、railsの`hidden_field`ではやっていないので、railsの`hidden_field`で動作するか不明。おそらくすると思う。`hidden_field`の使い方はわかると思うが念のため
[参考](http://qiita.com/NishidaRyu416/items/84a220c421241252e197)
それと、ボタンを押されたら再生するようにもした。


**お願い**
jsは全くわからないんで、効率の悪いコードとなっていると思うが、ご了承ください。

```
<h1>タイトル：<%=@word.title%></h1>

<p>問題：<%=@word.question%>
  <input id="question" type="hidden" value="<%=@word.question%>"/>
  <input id="question_language" type="hidden" value="<%=@word.question_language%>"/>
  <button id="question_btn" class="glyphicon glyphicon-play"></button>
</p>

<p>答え：<%=@word.answer%>
<input id="answer" type="hidden" value="<%=@word.answer%>"/>
  <input id="answer_language" type="hidden" value="<%=@word.answer_language%>"/>
  <button id="answer_btn" class="glyphicon glyphicon-play"></button>
</p>

<p>タグ：<%="#{@word.tag_list}"%></p>
<%=@word.favorites.count%>
<%= link_to "Edit", edit_word_path(@word), class:"btn btn-warning " %>
<%= link_to "Delete", word_path(@word), method: :delete, class:"btn btn-danger" %>
<%= link_to "fork",new_word_path(:id => @word.id),class:"btn btn-info" %>




<%= javascript_tag do %>

    //問題の音声
    document.querySelector('#question_btn').onclick = function () {

    // unsupported.
    if (!'SpeechSynthesisUtterance' in window) {
    alert('Web Speech API には未対応です.');
    return;
    }

    // 話すための機能をインスタンス化して、色々と値を設定します.
    var msg = new SpeechSynthesisUtterance();
    msg.volume = 1;
    msg.rate = 0.8;
    msg.pitch = 1;
    msg.text = document.querySelector('#question').value; // しゃべる内容
    msg.lang = document.querySelector('#question_language').value; // en-US or ja-UP

    // テキストスピーチ開始
    speechSynthesis.speak(msg);
    };

    //答えの音声
    document.querySelector('#answer_btn').onclick = function () {

    // unsupported.
    if (!'SpeechSynthesisUtterance' in window) {
    alert('Web Speech API には未対応です.');
    return;
    }

    // 話すための機能をインスタンス化して、色々と値を設定します.
    var msg = new SpeechSynthesisUtterance();
    msg.volume = 1;
    msg.rate = 0.8;
    msg.pitch = 1;
    msg.text = document.querySelector('#answer').value; // しゃべる内容
    msg.lang = document.querySelector('#answer_language').value; // en-US or ja-UP

    // テキストスピーチ開始
    speechSynthesis.speak(msg);
    };
   <%end%>
```
動作確認用
[自分のサイト](https://useful-bocubery-engine.herokuapp.com/words/5)
## 最後に

[デモ](https://codepen.io/matt-west/pen/wGzuJ)


*音質がかなり良くて、とても使いやすい、みなさんぜひ使ってみて！*