2013年12月16日月曜日

TwilioとGoogle Speech APIを使った音声変換について

Twilioを使うと、通話中に相手の会話を録音することができます。もちろん、録音されたデータはダウンロードが可能であり、留守番電話のような音声ファイルを使った様々なサービスを実装することができます。
Twilioには音声変換エンジンによる文字変換機能(transcribe)も用意されていますが、残念ながら日本語による変換はサポートされていません。

 そこで、日本語の音声ファイルをテキスト変換する方法として、GoogleのSpeech APIを用いる方法を調査してみましたので、今回はその方法をご紹介します。

 Twilioから音声変換するまでの流れ

  1. Twilio上での録音機能について
  2. 録音データの変換
  3. Google Speech APIの呼び出し



 Twilio上での録音機能について

※すでにTwilioについて詳しい方は、読み飛ばして構いません。
Twilio上で会話を録音するには、TwiMLの<Record>動詞を使います。次の例は、シンプルな留守番電話を実現します。

<?xml version="1.0" encoding="UTF-8"?>
<!-- page located at http://example.com/voicemail_record.xml -->
<Response>
  <Say>
    発信おんの後に、メッセージをどうぞ。
    終わりましたら何かキーを押してください。
  </Say>
  <Record
    action="http://foo.edu/handleRecording.php"
    method="GET"
    maxLength="20"
    finishOnKey="0123456789*#"
  />
  <Say>メッセージはお預かりできませんでした。</Say>
</Response>

この例では、ガイダンス(ちなみに「発信音」と指定すると「はっしんおと」と発声してしまうので、「発信おん」と指定するのがポイントですw)が流れた後に最大20秒の録音が開始されます(maxLengthパラメータで録音時間を指定でき、デフォルトは1時間となります)。録音を終了するキーに0〜9と#、*が設定されているため、何かキーを押すと録音を終了します。
発信音の後に無音が5秒続くと、録音はされずに最後の<Say>が実行されます。
正常に録音がされると、最後の<Say>は実行されずに、actionパラメータで指定されたURLに対してGETリクエストを送信します。

リクエストには以下のパラメータが付与されています。

RecordingUrl
 録音された音声ファイルのURL。
RecordingDuration
 録音された音声ファイルの長さ(秒)。
Digits
 ユーザによって押されたキー。

<Record>動詞のリファレンスは以下にあります。
https://jp.twilio.com/docs/api/twiml/record


 録音データの変換

録音されたデータは、明示的な削除を行わない限りTwilioサーバ側で保存されます。
なお、サーバー側の録音データについては、10,000分までは無料ですが、それ以降は1分につき0.1円が月額費用として請求されるので、不要になった録音データはREST APIを使って削除するようにしましょう。
録音データの削除に関するREST APIは以下にあります。
https://jp.twilio.com/docs/api/rest/recording

 Twilioサーバーに保存された録音データを抜き出すには、上記REST APIを利用することもできますが、もっとも一般的でかつ簡単な方法は<Record>動詞内で設定したactionパラメータを使うことです。
actionパラメータで指定したURLに対して、Twilio側から戻ってくるリクエストに含まれるRecordingUrlが録音データへのURLとなります。
なお、RecordingUrlの接続先オーディオファイルはWAV形式となります。RecordingUrlの最後に「.mp3」を指定すると、mp3形式でダウンロードすることもできます。

 Twilioで録音されたそれぞれのデータ形式は以下のとおりです。

WAV形式

チャンネル数:1
サンプリングレート:8000
量子化ビット:16
ビットレート:128k

mp3形式

チャンネル数:1
サンプリングレート:22050
量子化ビット:16
ビットレート:32.0k

 なお、音声ファイルのサイズは、WAV形式の方がmp3形式より3倍以上大きくなります。

 さて、ここからが音声変換のための準備となります。

 Speech APIを利用するためには、音声ファイルをFLAC形式に変換する必要があります。変換にはオープンソースのFLACを利用しますので、あらかじめ準備をしておく必要があります。CentOSではyumでインストールが可能ですし、MacやWindows版のFLACもここに公開されています。今回はCentOS上にインストールしたflacコマンドを利用します。
FLACはmp3からの変換に対応していないため、変換にはWAV形式の音声ファイルを利用します。WAVファイルのFLAC変換は以下のコマンドで行います。

 flac -n ソースファイル.wav
(-n:nは0〜8までの数値となり、圧縮率を指定します。8がもっとも圧縮率が高く、0は無圧縮です)

 このコマンドによって、拡張子がflacになった音声ファイルが作成されます。
他にもオプションが用意されていますが、詳しくはFLACのリファレンスを参照してください。
なお、FLACによる変換では、元データのサンプリングレートなどは変更されませんので、例えばTwilioの録音データ(WAV形式)であれば、サンプリングレートは8000のままとなります。


 Google Speech APIの呼出し

Googleは、Chromeブラウザ(バージョン25以降)において、JavaScriptから利用可能なWeb Speech APIを提供しています。なお、Web Speech APIについては、W3Cにて標準化が検討されている状況です。
今回は、GoogleがWeb Speech API向けに独自に用意している「Speech API」という機能を使って、REST形式で音声変換を行う方法を紹介します。
従来、このAPIは非公開APIとして存在していたものなのですが、最近になって正式に公開されました。また、今までの単純なREST方式ではなく、双方向の送受信にも対応しているため、より効率よく音声変換が可能になっています。

ただし、現在のところ以下の利用制限が設けられています(制限を解除することもできなくはなさそうなのですが、これ以上の調査はしていません)。

  • 開発用で、かつ個人利用であること
  • 1日のリクエスト数は50まで


 Speech APIを利用するためには、事前に以下のサイトにてAPIキーを取得する必要があります(別途、Google Cloud Consoleへのアカウント取得とサインインが必要です)。
https://cloud.google.com
ただし、Speech APIはUSもしくはCanadaユーザしか一覧には出てこないので、日本のユーザは、別途以下のChromium-devグループに加入することで表示されるようになります。
https://groups.google.com/a/chromium.org/

 私の場合は、Speech APIをONにしても、2日間はSpeech APIが認証エラーになり、3日目あたりから成功するようになりました(謎)。
なお、今回音声変換を行うためのAPIキーについては、WebApplicationのServer Keyを利用します(たぶん、Browser Keyでもいけると思います)。

 Google Speech APIについては、以下のブログが大変役に立ちます。
http://mikepultz.com/2013/07/google-speech-api-full-duplex-php-version/

上記サイト内には、PHPのプラグインも公開されているので、もしPHPを利用しているのであれば、APIキーさえ用意すればそのまま利用することもできるでしょう。

 PHPではなく、curlを使って変換をするコマンド例も以下に紹介します。この例では、ローカルフォルダにある、test.flacという音声ファイルを変換しています。

 curl -v "https://www.google.com/speech-api/full-duplex/v1/down?pair=3456123487654321" & curl -v -X POST "https://www.google.com/speech-api/full-duplex/v1/up?lang=ja-JP&lm=dictation&client=chromium&pair=3456123487654321&key=[SpeechAPIKey]" --header "Transfer-Encoding: chunked" --header "Content-Type: audio/x-flac; rate=8000"  --data-binary @test.flac

 コマンドを見てもらうとわかるように、送信用のURLと受信用のURLを同時に実行しています。それぞれのURLに含まれるpairパラメータについては、送信と受信で同じ16バイトのランダムな文字列を指定すれば良いようです。SpeechAPIKeyは、皆さんが取得したSpeech APIのServer Keyを指定します。
Twilioの録音データのサンプリングレートは8000ですので、rateパラメータには8000を指定しないといけません。また、日本語変換をするためには、langパラメータにja-JPを指定します。

 変換結果はJSON形式で戻ってきます。以下にサンプル音声データを変換した結果を示します(見やすいように整形しています)。

{
  "result":[
    {"alternative":[
      {"transcript":"長寿庵さんですか ざるそば 二つ島 おかめそばひとつ 大至急お願いします","confidence":0.51536459},
      {"transcript":"長寿庵さんですか ざるそば二つ島 おかめそばひとつ 大至急お願いします"},
      {"transcript":"長寿庵さんですか ざるそば 二傳 おかめそばひとつ 大至急お願いします"},
      {"transcript":"長寿庵さんですか ざるそばスタートおかめそばひとつ 大至急お願いします"},
      {"transcript":"長寿庵さんですか ざるそば 二ツ島おかめそばひとつ 大至急お願いします"}
    ],"final":true}
  ],"result_index":0
}

データを見るとわかるように、いくつか変換候補が戻ります。先頭の結果にconfidenceパラメータが戻っていますが、これが変換結果の信頼性を表しており、値が1に近ければ近いほど正確な変換ができたことを表すようです。

 Google Speech APIについては、ネット上でもあまり情報がなく、現時点では手探りの状態で参考になるかどうか判りませんが、変換精度はかなり良いようなので、今後に期待したいところです。

0 件のコメント:

コメントを投稿

必ず返信しますので、できればお名前をお書きくださいませ。
※URLは未記入で構いません。