メインコンテンツまでスキップ

リアルタイム音声認識ライブラリ Wrpの使い方

Wrpライブラリは、AmiVoice SDKと同じようなインタフェースでAmiVoice APIのWebSocketインタフェースを使ったリアルタイムアプリケーションの開発を行うことができます。ストリーミングの音声を送信し、逐次結果を受け取ることができます。このライブラリは、Java、C#、C++、Python、PHPなどの言語で利用できます。

クライアントプログラムの概要

Wrpを使ったプログラムは以下のような流れになります。

図. コマンドとイベント

メソッド

クライアントプログラムは以下の処理を順に行います。()には対応するWrpのメソッドを記載しています。

  1. 接続 (connect)
  2. 音声認識のリクエスト (feedDataResume)
  3. 音声データの送信 (feedData)
  4. 音声データの送信終了 (feedDataPause)
  5. 切断 (disconnect)

イベント

サーバからの発話検出や音声認識の通知イベントは、どちらもリスナークラスのメソッドを通じて得られます。以下の5つのイベントがあります。()にはWrpの実装すべきメソッド名を記載しています。

  • 発話の開始が検出された時に通知されるイベント utteranceStarted(startTime)
  • 発話の終了が検出された時に通知されるイベント utteranceEnded(endTime)
  • 音声認識の処理が開始された時に通知されるイベント resultCreated()
  • 認識の途中結果の通知イベント resultUpdated(result)
  • 認識結果の通知イベント resultFinalized(result)

認識結果の通知イベント resultFinalized(result)は必ず実装してください。その他、必要に応じてサーバからの通知に応じた処理を実装してください。

実装ガイド

各言語ごとのサンプルを示しながら、ステップバイステップでWrpの使い方を説明します。

以下に掲載しているコード例は、全てGitHubのリポジトリadvanced-media-inc/amivoice-api-client-libraryで公開しているWrpSimpleTesterからの抜粋です。コード全体については、以下のソースファイルを参照してください。

実行方法やファイル構成などの説明はクライアントライブラリのサンプルプログラムWrpSimpleTesterを参照してください。

1. 初期化

Wrpクラスのインスタンスを生成します。

        // WebSocket 音声認識サーバの初期化
com.amivoice.wrp.Wrp wrp = com.amivoice.wrp.Wrp.construct();

2. リスナークラスの実装

com.amivoice.wrp.WrpListenerクラスを継承して、イベントハンドラを実装します。

音声認識の結果はresultFinalizedの引数resultで得られます。詳細は、音声認識結果フォーマットのWebSocket インタフェースを参照してください。また、認識結果テキストは、UTF-8でエンコードされ、Unicodeエスケープされています。結果テキストについても参照してください。

以下のコードでは、utteranceStartedutteranceEndedresultCreatedresultUpdatedresultFinalizedの各メソッドで標準出力にログを出すように実装しています。これらのメソッドを実装したリスナーのインスタンスをwrpインスタンスのwrp.setListener(listener)で設定します。結果テキストのUnicodeエスケープをtext_メソッドでデコードしています。text_メソッドは、GitHubで完全なコードを公開しています。

public class WrpTester implements com.amivoice.wrp.WrpListener {
public static void main(String[] args) {
// WebSocket 音声認識サーバイベントリスナの作成
com.amivoice.wrp.WrpListener listener = new WrpTester(verbose);
wrp.setListener(listener);
}

@Override
public void utteranceStarted(int startTime) {
System.out.println("S " + startTime);
}

@Override
public void utteranceEnded(int endTime) {
System.out.println("E " + endTime);
}

@Override
public void resultCreated() {
System.out.println("C");
}

@Override
public void resultUpdated(String result) {
System.out.println("U " + result);
String text = text_(result);
if (text != null) {
System.out.println(" -> " + text);
}
}

@Override
public void resultFinalized(String result) {
System.out.println("F " + result);
String text = text_(result);
if (text != null) {
System.out.println(" -> " + text);
}
}

3. 接続 (connect)

音声認識サーバへの接続を行います。

このメソッドを呼び出す前に、必ず設定しなければならないパラメータは以下です。

  • serverURL ... WebSocketインタフェースのエンドポイント

以下のURLを指定してください。

wss://acp-api.amivoice.com/v1/     (ログ保存あり)
wss://acp-api.amivoice.com/v1/nolog/ (ログ保存なし)

以下のパラメータを設定することで動作を調整できます。

  • proxyServerName ... クライアントプログラムがプロキシサーバを経由して接続する場合に指定
  • connectTimeout ... サーバとの接続タイムアウト。単位はミリ秒。
  • receiveTimeout ... サーバからのデータ受信タイムアウト。単位はミリ秒。

サーバ側のタイムアウトについては、制限事項を参照してください。

以下のコードは、音声認識サーバへの接続を行います。verbosefalseの場合は、エラーメッセージを表示しません。

        wrp.setServerURL(serverURL);
wrp.setProxyServerName(proxyServerName);
wrp.setConnectTimeout(connectTimeout);
wrp.setReceiveTimeout(receiveTimeout);

// WebSocket 音声認識サーバへの接続
if (!wrp.connect()) {
if (!verbose) {
System.out.println(wrp.getLastMessage());
}
System.out.println("WebSocket 音声認識サーバ " + serverURL + " への接続に失敗しました。");
return;
}

4. 音声認識のリクエスト (feedDataResume)

音声認識のリクエストを送信します。このメソッドはリクエストパラメータに指定した適切な音声認識サーバへの接続や、単語登録の準備ができるまでブロックします。失敗した場合は、エラーを返します。詳細は、sコマンド応答パケットのエラーメッセージを参照してください。

このメソッドを呼び出す前に、必ず設定しなければならないパラメータは以下です。

  • codec ... 音声フォーマットの指定。対応している音声のフォーマットは、音声認識の結果フォーマットを参照してください。
  • grammarFileNames ... 接続エンジン名。対応しているエンジンは、音声認識のエンジンを参照してください。
  • authorization ... 認証情報。マイページに記載されたAPPKEYを指定してください。または、ワンタイム APPKEYを指定してください。

以下のパラメータを設定することで動作を調整できます。

  • profileId
  • profileWords
  • keepFillerToken
  • segmenterProperties
  • resultUpdatedInterval

詳細はパラメータの詳細を参照してください。

危険

デッドロックしてしまうため、feedDataResumeメソッドをイベントの通知を受け取るためのリスナークラスのメソッド、resultFinalizedなどから呼び出さないでください。

以下のコードは、上記のパラメータに基づいて音声認識のリクエストをサーバに送信し、エラーが起きた場合は標準出力にメッセージを表示します。verbosefalseの場合は、エラーメッセージを表示しません。

        wrp.setCodec(codec);
wrp.setGrammarFileNames(grammarFileNames);
wrp.setAuthorization(authorization);

// WebSocket 音声認識サーバへの音声データの送信の開始
if (!wrp.feedDataResume()) {
if (!verbose) {
System.out.println(wrp.getLastMessage());
}
System.out.println("WebSocket 音声認識サーバへの音声データの送信の開始に失敗しました。");
break;
}

5. 音声データの送信 (feedData)

次に音声データを送信します。このメソッドはブロックしません。サーバ側で何らかのエラーが発生した場合は、次のメソッド呼び出し時にエラーを返します。エラーの内容についてはpコマンド応答パケットのエラーメッセージを参照してください。音声データを送信し始めると、サーバ側の処理に応じてリスナークラスのメソッドが呼び出されます。

備考
  • feedDataResumeで指定したcodecにあった音声データを送信してください。もしフォーマットが異なっても、エラーにはなりませんが、レスポンスに非常に時間がかかったり、認識結果が正しく得られません。
  • 送信した音声データから発話を検出できなかった場合、リスナークラスのメソッドは呼び出されません。以下のような理由が考えられますので確認してください。
    • 音声が全く含まれていない。もしくは非常に音量が小さい。録音システムがミュートされていないか、音量設定が適切かどうかなどを確認してください。
    • 音声フォーマットと音声データが合っていない。音声フォーマットを確認してください。
注記
  • 1回のfeedDataメソッドで送信できる音声データのサイズは最大で16MBです。データサイズがそれ以上であれば、分割してください。
  • 音声データの分割は、任意の箇所で行って問題ありません。wavのチャンクや、mp3、flac、opusなどのフレーム境界を意識する必要はありません。
  • 途中で送信するデータのフォーマットを変更することはできません。音声フォーマットを変更する場合は、eコマンドで終了し、sから新しく音声認識のリクエストをしてください。ヘッダありの音声ファイルの場合も同様にファイル毎にeコマンドで終了し、sから新しく音声認識のリクエストをしてください。

以下のコードは、audioFileNameに指定された音声データファイルから音声データを読み込み、WebSocket音声認識サーバに送信する処理です。sleepTime-1の場合は、認識結果情報待機数が1以下になるまでスリープします。verbosefalseの場合は、エラーメッセージを表示しません。

                    try (FileInputStream audioStream = new FileInputStream(audioFileName)) {
// 音声データファイルからの音声データの読み込み
byte[] audioData = new byte[4096];
int audioDataReadBytes = audioStream.read(audioData, 0, audioData.length);
while (audioDataReadBytes > 0) {
// スリープ時間が計算されているかどうかのチェック
if (sleepTime >= 0) {
// スリープ時間が計算されている場合...
// 微小時間のスリープ
wrp.sleep(sleepTime);
} else {
// スリープ時間が計算されていない場合...
// 微小時間のスリープ
wrp.sleep(1);

// 認識結果情報待機数が 1 以下になるまでスリープ
int maxSleepTime = 50000;
while (wrp.getWaitingResults() > 1 && maxSleepTime > 0) {
wrp.sleep(100);
maxSleepTime -= 100;
}
}

// WebSocket 音声認識サーバへの音声データの送信
if (!wrp.feedData(audioData, 0, audioDataReadBytes)) {
if (!verbose) {
System.out.println(wrp.getLastMessage());
}
System.out.println("WebSocket 音声認識サーバへの音声データの送信に失敗しました。");
break;
}

// 音声データファイルからの音声データの読み込み
audioDataReadBytes = audioStream.read(audioData, 0, audioData.length);
}
} catch (IOException e) {
System.out.println("音声データファイル " + audioFileName + " の読み込みに失敗しました。");
}

6. 音声データの送信終了 (feedDataPause)

音声データの送信が完了したときに呼び出してください。このメソッドは音声認識処理が終わるまでブロックします。何らかの理由で要求が失敗する可能性があります。詳細はeコマンド応答パケットのエラーメッセージを参照してください。

危険

デッドロックしてしまうため、feedDataPauseメソッドをイベントの通知を受け取るためのリスナークラスのメソッド、resultFinalizedなどから呼び出さないでください。

備考

ストリーミングではなく、一度に音声データを送信した場合は音声認識処理に時間がかかりますので、結果が返ってくるまでしばらく時間がかかります。送信した音声の0.5〜1.5倍程度の時間を想定してください。

以下のコードは、音声データをすべて送信したことをサーバに伝え、結果が返ってくるまでブロックします。verbosefalseの場合は、エラーメッセージを表示しません。

                    // WebSocket 音声認識サーバへの音声データの送信の完了
if (!wrp.feedDataPause()) {
if (!verbose) {
System.out.println(wrp.getLastMessage());
}
System.out.println("WebSocket 音声認識サーバへの音声データの送信の完了に失敗しました。");
break;
}

7. 切断 (disconnect)

最後に音声認識サーバとのコネクションを切断します。

            // WebSocket 音声認識サーバからの切断
wrp.disconnect();

クライアントプログラムの状態遷移

クライアントプログラムは以下の状態遷移を行います。

その他のドキュメント