Twilioを使うと、通話中に相手の会話を録音することができます。もちろん、録音されたデータはダウンロードが可能であり、留守番電話のような音声ファイルを使った様々なサービスを実装することができます。
Twilioには音声変換エンジンによる文字変換機能(transcribe)も用意されていますが、残念ながら日本語による変換はサポートされていません。
そこで、日本語の音声ファイルをテキスト変換する方法として、GoogleのSpeech APIを用いる方法を調査してみましたので、今回はその方法をご紹介します。
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
なお、サーバー側の録音データについては、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で録音されたそれぞれのデータ形式は以下のとおりです。
サンプリングレート:8000
量子化ビット:16
ビットレート:128k
サンプリングレート: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がWeb Speech API向けに独自に用意している「Speech API」という機能を使って、REST形式で音声変換を行う方法を紹介します。
従来、このAPIは非公開APIとして存在していたものなのですが、最近になって正式に公開されました。また、今までの単純なREST方式ではなく、双方向の送受信にも対応しているため、より効率よく音声変換が可能になっています。
ただし、現在のところ以下の利用制限が設けられています(制限を解除することもできなくはなさそうなのですが、これ以上の調査はしていません)。
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については、ネット上でもあまり情報がなく、現時点では手探りの状態で参考になるかどうか判りませんが、変換精度はかなり良いようなので、今後に期待したいところです。
Twilioには音声変換エンジンによる文字変換機能(transcribe)も用意されていますが、残念ながら日本語による変換はサポートされていません。
そこで、日本語の音声ファイルをテキスト変換する方法として、GoogleのSpeech APIを用いる方法を調査してみましたので、今回はその方法をご紹介します。
Twilioから音声変換するまでの流れ
- Twilio上での録音機能について
- 録音データの変換
- 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については、ネット上でもあまり情報がなく、現時点では手探りの状態で参考になるかどうか判りませんが、変換精度はかなり良いようなので、今後に期待したいところです。