Google Cloud Speech API Beta でwavファイルの音声認識

***2016年8月現在の情報です***

[Google Cloud Speech API Beta](https://cloud.google.com/speech/) でwavファイルの音声認識の試用メモ。

## CLOUD SPEECH API

[Google Cloud Speech API Beta](https://cloud.google.com/speech/)にある通り、音声認識のAPI。

- 80か国語対応
- 雑音に強い
- コンテキストに合った認識
- デバイス非依存
- リアルタイムと録音済みファイル両対応

とのことで、お手軽な高性能ASRらしい。

## 資料

[公式ドキュメント](https://cloud.google.com/speech/docs/)
[pythonサンプルコード](https://github.com/GoogleCloudPlatform/python-docs-samples/tree/master/speech/api)

## CLI (Google Cloud SDK+curl) から使う方法

[Quickstart](https://cloud.google.com/speech/docs/getting-started)によると、

1. Google Cloud Platformアカウントを作る
2. プロジェクトを作り、Speech APIを有効化
3. Service Account keyファイルを生成し、手元にダウンロード
4. コマンドラインツールGoogle Cloud SDKをインストールしたうえで、上記Service Account keyファイルを使って認証トークンを得る
5. 得られた認証トークンを使い、あらかじめ用意したwavファイル等の音声データをAPIに投げて認識結果を得る

秘密鍵を含んだService Account keyファイル (json) を生成し、それを使って都度認証トークンを得る。

### プロジェクト作成からService Account keyファイル取得まで

[QuickStart](https://cloud.google.com/speech/docs/getting-started)の Set Up Your Projectの項のとおり。

が、6のService Account作成で、"new service account" を作成する際、[ドキュメント](https://cloud.google.com/speech/docs/common/auth#set_up_a_service_account) に無いRoleという項目が出来てて戸惑う。

Service Accountの登録が済むとjsonファイルをダウンロードできるので、任意の場所に保存する。秘密鍵が含まれるので人目にさらさないこと。

### Google Cloud SDKで認証トークンを得る

1. [Google Cloud SDK](https://cloud.google.com/sdk/)をインストールし、```gcloud```コマンドを叩けるようにする。
2. 上で取得したService Account key ファイルを使って認証トークンを得る

   ```$ gcloud auth activate-service-account --key-file=account keyファイルのパス
   $ gcloud auth print-access-token
   ```
   帰ってきた認証トークンを覚えておく

### CurlでAPI呼び出し

[QuickStart](https://cloud.google.com/speech/docs/getting-started)のMake a Speech API Requestの通りに```sync-request.json```を作成し、

```sync-request.json
{
  "config": {
      "encoding":"FLAC",
      "sample_rate": 16000
  },
  "audio": {
      "uri":"gs://cloud-samples-tests/speech/brooklyn.flac"
  }
}
```

sync-request.jsonがあるディレクトリで

```
$ curl -s -k -H "Content-Type: application/json" \
    -H "Authorization: Bearer 上で得た認証トークン" \
    https://speech.googleapis.com/v1beta1/speech:syncrecognize \
    -d @sync-request.json
```
うまくいけばjsonで認識結果が返ってくる。

### 音声データと認識内容の設定方法

入力ファイルの場所や形式の設定はRequest bodyにのjson (上の例だと```sync-request.json```) で指定する。
例の```sync-request.json```ではGoogle Cloud Storageにあらかじめ配置されたサンプルの[flac](https://ja.wikipedia.org/wiki/FLAC)ファイルを使っているが、手元の音声データを送ることも勿論可能だしflac以外のエンコードにも対応している。

### 手元にある音声ファイルを送る

[Rest APIのreference] (https://cloud.google.com/speech/reference/rest/)の、[syncRecognize](https://cloud.google.com/speech/reference/rest/v1beta1/speech/syncrecognize)の通り、Request bodyの```config```で音源や認識の設定を、```audio```で音声データを指定する。

```audio```の指定は[RecognitionAudio](https://cloud.google.com/speech/reference/rest/v1beta1/RecognitionAudio)の通り、```uri``` か```content```で、手元の音声ファイルを送る場合はBase64で文字列にエンコードして```content```として送ればいいらしい。

サンプルはエンコード方式がFLAC、サンプリングレートが16000(16khz)になってるので、送る音声データに合わせること。

## pythonでSpeech APIを使う

[チュートリアル](https://cloud.google.com/speech/docs/rest-tutorial)の通り、```glcoud```コマンド + curlではなく、pythonからもSpeech APIを呼べる (Node.jsのサンプルもある)
この手順だとGoogle Cloud SDKは要らないが、代わりに[Google API Client Library](https://developers.google.com/api-client-library/python/start/installation)が必要。curlでいけるんだからライブラリは要らないかと思いきや、[API Discovery Service](https://developers.google.com/discovery/) & 認証トークン取得のためにGoogle API Client Libraryが使われている。これらが必要なければ前述のcurlに倣ってライブラリなしでも使えそう。

### Service Account keyファイルの取得

上記CLIの手順1-3と同じ。

### Application Default Credentialの設定

手順は[サンプルコード](https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/speech/api/speech_rest.py)の通りだが、こちらは認証トークン取得のためのService Account keyファイルを事前に環境変数```GOOGLE_APPLICATION_CREDENTIALS```に設定しておく必要がある:

   ```$ export GOOGLE_APPLICATION_CREDENTIALS=Service Account ファイルのパス```

これを[Application Default Credential](https://cloud.google.com/speech/docs/common/auth#authenticating_with_application_default_credentials)としてGoogleCredentials.get_application_default().create_scoped()メソッドが参照することで認証トークンが得られるとのこと。

### APIの呼び出し

[サンプルコード](https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/speech/api/speech_rest.py)の通り:

```$ python speech_rest.py 音声ファイル.wav```

で認識結果が表示される。

 **注意**

- *日本語音声を認識する場合、bodyの```languageCode```を```en-US```から```ja-UP```に変更する。*
- FLACでエンコードされたデータを送りたい場合はbodyの```encoding```をFLACにすること。
- サンプルだと認識結果をjson.dumps()しているだけなので、日本語を認識した場合は正しく表示されるよう対応が必要。

このサンプルは入力ファイル1つに対する処理なので、複数ファイルを認識させたい場合はAPI Discoverとトークン取得を繰り返さないようにした方が良さそう。

認証トークンはそれなりの頻度で更新されるようなので、トークン再取得のケアも要る。テスト中(体感15-30分ぐらい?)にいきなり401が帰ってきて何だろう？と思ったらトークンが更新されてた、、ってことがあった。


## 使用感

定量的じゃなくて申し訳ないですが: 

- 認識にある程度の時間がかかる (2-4秒程度?)
- 認識精度はかなり高い。結構大きな雑音（マイクのそばで音楽を流したり）があってもちゃんと聞き取る。何にも設定しないでこの精度ってすごい
   - 雑音が人の話声だとどうなるか試してみたい
- コンテキスト関連のオプションを試してないので、今後使ってみたい
- QuickStartに **Learn in 5 minutes** ってあるが、私には5分じゃ全く無理で悲しくなった