Speech Recognition API と Yandex Translation API を使って 音声自動翻訳アプリを作成

# はじめに
たまたま音声認識APIがあることを知って簡単に動かせた
→ 翻訳にかけれたら便利だなと思ったので簡単に使える翻訳APIを調べて組み合わせてみた。

# 使用するAPIについて

## [SpeechRecognition](https://developer.mozilla.org/ja/docs/Web/API/SpeechRecognition/SpeechRecognition)
- HTML5に備わってるAPI (Mozilla作)
- 音ブラウザで音声を認識してくれる
- 参考：[Speech Recognition API でブラウザ音声認識を試す](https://qiita.com/yunayunanaka/items/75c1ade41b6156d304d8)

## [YandexTranslation](https://github.com/RytNszn/mylaps-dashboard)
- Yandexがロシア版Googleみたいなもので、そのYandexが出してる翻訳API
- APIの使用には無料登録が必要
- 使い方が簡単そうだったの試しに使ってみた
- 参考：[Yandex Translation API を使って翻訳機能を試す](https://qiita.com/yunayunanaka/items/398716f6c4d2292a59ec)
   
# 準備

Yandexの登録とAPIKeyの発行が必要
参考：[Yandex Translation API を使って翻訳機能を試す](https://qiita.com/yunayunanaka/items/398716f6c4d2292a59ec)

# 音声認識と翻訳を組み合わせてみる

## 仕様
1. 自分の話す言語を選択
2. 翻訳語の言語を選択
3. press and start speak ボタン押下 → 音声認識開始
4. 音声認識結果をtextareaに出力
5. 音声認識するごとに自動翻訳して、textareaに別途出力
6. finish speak and press ボタン押下 → 音声認識終了
7. clear ボタン押下 → 出力結果を削除する

画面はこんな感じ
![6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431932/0369d15b-5d6b-a304-9946-e2f94d1139c2.png)


## ソースコード

```index.html
<!DOCTYPE html>
<html>

<head lang="ja-JP">
  <meta charset="utf-8">
  <title>translate your speaking!</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>

<body>

  <div>
    <h3>1. Choose language</h3>

    <b>Your Language</b>
    <select id="lang-before">
      <option value="en-US">English</option>
      <option value="ja-JP" selected>Japanese</option>
    </select>

    <b>Translate to</b>
    <select id="lang-after">
      <option value="en" selected>English</option>
      <option value="ja">Japanese</option>
      <option value="zh">Chinese</option>
      <option value="id">Indonesian</option>
      <option value="vi">Vietnamese</option>
      <option value="ko">Korean</option>
      <option value="ne">Nepali</option>
      <option value="th">Thai</option>
      <option value="fr">French</option>
      <option value="de">German</option>
      <option value="pt">Portuguese</option>
      <option value="es">Spanish</option>
      <option value="pl">Polish</option>
      <option value="ru">Russian</option>
    </select>
  </div>


  <div>
    <h3>2. try speak translation</h3>
    <button id="start" onclick="startbutton()">press and start speak</button>
    <button id="stop" onclick="stopbutton()">finish speak and press </button>
    <button id="clear" onclick="clearbutton()">clear</button>
  </div>

  <div>
    <h3>3. Result you speak</h3>
    <div>
      <textarea id="textarea" rows=10 cols=80></textarea>
    </div>
  </div>

  <div>
    <h3>4. Result translation</h3>
    <div>
      <textarea id="autotextarea" rows=10 cols=80></textarea>
    </div>
  </div>
  <script src="index.js"></script>

</body>

</html>
```

```index.js
const textarea = document.getElementById("textarea")
const autotextarea = document.getElementById("autotextarea")
const DateTimeFormat = 'YYYY/MM/DD hh:mi:ss'

const SpeechRecognition = webkitSpeechRecognition || SpeechRecognition;
const rec = new SpeechRecognition();
rec.continuous = true;
rec.interimResults = false;

// rec.start(); // ページ開いた瞬間から音声認識開始する場合ここでstartするとよさそう

rec.onresult = function (e) {
  console.log("on result")
  for (var i = e.resultIndex; i < e.results.length; ++i) {
    if (e.results[i].isFinal) {
      const str = e.results[i][0].transcript;
      console.log('Recognised: ' + str);
      textarea.value += str
      textarea.value += "\r\n"
      translation(str)
    }
  }
}
function startbutton() {
  console.log("start button")
  rec.lang = document.getElementById("lang-before").value
  const time = timestamp()
  textarea.value += time
  textarea.value += "\r\n"
  autotextarea.value += timestamp()
  autotextarea.value += "\r\n"
  rec.start();
}

function stopbutton() {
  console.log("stop buton")
  rec.stop();
}

function clearbutton() {
  console.log("clear button")
  textarea.value = "";
  autotextarea.value = ""
}

function translation(text) {
  const lang = document.getElementById("lang-after").value
  const url = getURL(lang, text)
  const request = new XMLHttpRequest();
  request.open('GET', url);
  request.onreadystatechange = function () {
    if (request.readyState != 4) {
      // requesting
    } else if (request.status != 200) {
      console.log("http request failed.")
    } else {
      console.log("success", text, request.responseText);
      autotextarea.value += lang + ":" + JSON.parse(request.responseText).text
      autotextarea.value += "\r\n"
    }
  };
  request.send(null);
}

function getURL(lang, text) {
  const base_url = "https://translate.yandex.net/api/v1.5/tr.json/translate"
  const api_key = "XXXXXXXXXXXXXXXXXXXXX" // 発行したAPIKey
  const format = "html"
  return base_url + '?key=' + api_key + "&text=" + text + "&lang=" + lang + "&format=" + format
}

function timestamp() {
  const d = new Date();
  return DateTimeFormat
    .replace(/YYYY/g, String(d.getFullYear()))
    .replace(/MM/g, ('0' + (d.getMonth() + 1)).slice(-2))
    .replace(/DD/g, ('0' + d.getDate()).slice(-2))
    .replace(/hh/g, ('0' + d.getHours()).slice(-2))
    .replace(/mi/g, ('0' + d.getMinutes()).slice(-2))
    .replace(/ss/g, ('0' + d.getSeconds()).slice(-2));
}
```

## 結果

うまくいきました
ただ、認識してからAPI投げるので、結果が出るまでは遅いかも
![5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431932/bf966c23-dd7a-e86a-2286-14df2603bcc3.png)