コマンドと応答
WebSocketインタフェースを使って、音声データをストリーミングとして送信するときのコマンドと応答について説明します。
クライアントは以下の表のコマンドを使ってAPIに音声認識の開始、終了のリクエスト、および、データの送信をします。s
とe
はAPIからの応答を待って次のコマンドを送ります。エラーが起きたときにはエラー応答を返します。
名前 | 説明 |
---|---|
sコマンド | クライアントからの音声認識リクエストのコマンド |
pコマンド | クライアントからの音声データ送信のコマンド |
eコマンド | クライアントからの音声認識の終了のリクエストのコマンド |
APIからは、処理の進捗に応じて以下の表のイベントを返します。
名前 | 説明 |
---|---|
Sイベント | 発話検出プロセスによる発話の開始を通知するイベント |
Eイベント | 発話検出プロセスによる発話の終了を通知するイベント |
Cイベント | 音声認識プロセスによる音声認識の開始を通知するイベント |
Uイベント | 音声認識プロセスによる声認識の途中結果を通知するイベント |
Aイベント | 音声認識プロセスによる音声認識の完了と結果を通知するイベント |
Gイベント | サーバで生成された情報を通知するイベント。関連機能を利用していない場合は発生しません。 |
音声ストリーミングを使ったアプリケーションのコマンドとイベントの一般的な流れは以下のようになります。
S
とE
は発話検出の結果として、C
、U
、A
は音声認識の結果として得られます。発話区間の長さや基盤システムの混雑具合によって、イベントの順序が異なることがあります。例えば、上記の図ではS
とE
の間にC
が来ていますが、E
の後になることもあります。
ここではある音声データで、発話検出によって、3つの発話区間が検出されるケースを例に説明します。
WebSocketインタフェースでストリーミングのデータソースから1秒ずつデータをAPIに送信したときの、クライアントからのコマンドの送信とAPIからの応答のイベントの流れをログを使って説明します。
command>>>
から始まる行はクライアントからのコマンドの送信ですmessage<<<
から始まる行はAPIからの応答のイベントです
全体のログは以下のとおりです。見やすさのためにAPIからのイベントをハイライトしています。
0:00:00.000 open> wss://acp-api.amivoice.com/v1/
0:00:00.161 open # WebSocketの接続
0:00:00.161 command>>> s 16k -a-general segmenterProperties="useDiarizer=1" resultUpdatedInterval=1000 authorization=XXXXXXXXXXXXXXXX
0:00:00.226 message<<< s # 音声認識のリクエストsコマンドの応答
0:00:00.226 command>>> p [..(32000 bytes)..] # 1秒目のデータ送信
0:00:01.232 command>>> p [..(32000 bytes)..] # 2秒目のデータ送信
0:00:02.236 command>>> p [..(32000 bytes)..] # 3秒目のデータ送信
0:00:03.241 command>>> p [..(32000 bytes)..] # 4秒目のデータ送信
0:00:04.245 command>>> p [..(32000 bytes)..] # 5秒目のデータ送信
0:00:05.250 command>>> p [..(32000 bytes)..] # 6秒目のデータ送信
0:00:06.254 command>>> p [..(32000 bytes)..] # 7秒目のデータ送信
0:00:07.257 command>>> p [..(32000 bytes)..] # 8秒目のデータ送信
0:00:07.291 message<<< S 6200 # [発話1] 6.2秒目に発話が検出された
0:00:07.297 message<<< C # [発話1] 音声認識処理が開始された
0:00:08.262 command>>> p [..(32000 bytes)..] # 9秒目のデータ送信
0:00:08.315 message<<< E 7450 # [発話1] 7.45秒目に発話が終了した
0:00:08.315 message<<< U {...} # [発話1] 途中結果
0:00:08.446 message<<< A {...} # [発話1] 発話区間の結果
0:00:09.267 command>>> p [..(32000 bytes)..] # 10秒目のデータ送信
0:00:10.270 command>>> p [..(32000 bytes)..] # 11秒目のデータ送信
0:00:10.309 message<<< S 8600 # [発話2] 8.6秒目に発話が検出された
0:00:10.327 message<<< C # [発話2] 音声認識処理が開始された
0:00:11.272 command>>> p [..(32000 bytes)..] # 12秒目のデータ送信
0:00:11.337 message<<< U {...} # [発話2] 途中結果
0:00:12.274 command>>> p [..(32000 bytes)..] # 13秒目のデータ送信
0:00:12.321 message<<< U {...} # [発話2] 途中結果
0:00:13.277 command>>> p [..(32000 bytes)..] # 14秒目のデータ送信
0:00:13.301 message<<< E 11650 # [発話2] 11.65秒目に発話が検出された
0:00:13.304 message<<< S 12000 # [発話3] 12.00秒目に発話が検出された
0:00:13.311 message<<< U {...} # [発話3] 途中結果
0:00:13.343 message<<< A {...} # [発話3] 発話区間の結果
0:00:14.282 command>>> p [..(32000 bytes)..] # 15秒目のデータ送信
0:00:14.336 message<<< C # [発話3] 音声認識処理が開始された
0:00:15.287 command>>> p [..(32000 bytes)..] # 16秒目のデータ送信
0:00:15.344 message<<< U {...} # [発話3] 途中結果
0:00:16.289 command>>> p [..(32000 bytes)..] # 17秒目のデータ送信
0:00:16.337 message<<< U {...} # [発話3] 途中結果
0:00:17.291 command>>> p [..(22968 bytes)..] # 18秒目のデータ送信
0:00:17.345 message<<< U {...} # [発話3] 途中結果
0:00:18.297 command>>> e # 音声の送信がすべて終わったのでeコマンドを送信してセッションを終了する
0:00:18.341 message<<< U {...} # [発話3] 途中結果
0:00:18.347 message<<< E 17700 # [発話3] 17.70秒目に発話が検出された
0:00:18.347 message<<< U {...} # [発話3] 途中結果
0:00:18.512 message<<< A {...} # [発話3] 発話区間の結果
0:00:18.574 message<<< e # セッションの終了の応答
0:00:18.574 close> # WebSocketのクライアントからのクローズ
0:00:18.595 close # WebSocketのクローズの応答
以下ではステップごとに説明します。
まず、WebSocketでAmiVoice APIのエンドポイントに接続し、s
コマンドで音声認識のリクエストをします。APIからはs
コマンドの応答が返ります。
0:00:00.000 open> wss://acp-api.amivoice.com/v1/
0:00:00.161 open # WebSocketの接続
0:00:00.161 command>>> s 16k -a-general segmenterProperties="useDiarizer=1" resultUpdatedInterval=1000 authorization=XXXXXXXXXXXXXXXX
0:00:00.226 message<<< s # 音声認識のリクエストsコマンドの応答
リクエストの成功後にクライアントからp
コマンドで音声データを1秒ずつ送信しています。8秒目のデータ送信した後にAPIからS
(発話検出)のイベントが送信されています。
0:00:00.226 command>>> p [..(32000 bytes)..] # 1秒目のデータ送信
0:00:01.232 command>>> p [..(32000 bytes)..] # 2秒目のデータ送信
0:00:02.236 command>>> p [..(32000 bytes)..] # 3秒目のデータ送信
0:00:03.241 command>>> p [..(32000 bytes)..] # 4秒目のデータ送信
0:00:04.245 command>>> p [..(32000 bytes)..] # 5秒目のデータ送信
0:00:05.250 command>>> p [..(32000 bytes)..] # 6秒目のデータ送信
0:00:06.254 command>>> p [..(32000 bytes)..] # 7秒目のデータ送信
0:00:07.257 command>>> p [..(32000 bytes)..] # 8秒目のデータ送信
0:00:07.291 message<<< S 6200 # [発話1] 6.2秒目に発話が検出された
その後、C
(音声認識開始)してから、A
(発話区間の結果)のイベントが順に得られます。また、途中で7.45秒目で発話が終わったことを示すE
(終話検出)のイベントが得られています。s
コマンドで接続するときにresultUpdatedInterval=1000
としてリクエストしているため、1秒毎にU
(途中結果)が得られます。
0:00:07.297 message<<< C # [発話1] 音声認識処理が開始された
0:00:08.262 command>>> p [..(32000 bytes)..] # 9秒目のデータ送信
0:00:08.315 message<<< E 7450 # [発話1] 7.45秒目に発話が終了した
0:00:08.315 message<<< U {...} # [発話1] 途中結果
0:00:08.446 message<<< A {...} # [発話1] 発話区間の結果
以降も発話検出と音声認識処理が残りの2つの発話について繰り返されます。
音声データを送信完了した後に、e
コマンドを送信してセッションを終了します。APIはすべての発話検出、音声認識処理を完了したらセッションの終了の応答としてe
のイベントを返します。
0:00:18.297 command>>> e # 音声の送信がすべて終わったのでeコマンドを送信してセッションを終了する
0:00:18.341 message<<< U {...} # [発話3] 途中結果
0:00:18.347 message<<< E 17700 # [発話3] 17.70秒目に発話が検出された
0:00:18.347 message<<< U {...} # [発話3] 途中結果
0:00:18.512 message<<< A {...} # [発話3] 発話区間の結果
0:00:18.574 message<<< e # セッションの終了の応答
0:00:18.574 close> # WebSocketのクライアントからのクローズ
0:00:18.595 close # WebSocketのクローズの応答
この18秒のセッション全体については、前述のログのコメントの説明を見てください。
A
やU
イベントのレスポンスには結果があります。詳細は音声認識の結果フォーマットを参照してください。WebSocketのコマンドとイベントについてはWebSocket インタフェースも参照してください。
上記のログにおけるコマンドとイベントのシーケンスは以下のようになります。以下の図ではp
コマンドは省略しています。
エラー応答
クライアントが送信したs
コマンド、p
コマンド、e
コマンドが何らかの原因で失敗した場合、例えば、コマンドの送信手順に誤りがあった場合、制限事項に抵触した場合、基板側の問題が起きた場合など、応答にエラーメッセージが含まれるエラーレスポンスを返すことがあります。
成功レスポンス
s
p
e
エラーレスポンス
s エラーメッセージ
p エラーメッセージ
e エラーメッセージ
エラーレスポンスの場合、s
コマンドを送信する前の初期状態に戻ります。再度s
コマンドからリクエストを送信してください。詳細はパケットおよび状態遷移の音声供給状態遷移図を参照してください。
エラーメッセージを参照し、クライアントエラーの場合は原因を修正してから、AmiVoice API基板側のサーバエラーの場合はしばらく待ってから再度リクエストを送信してください。制限事項によるエラーについては制限事項を参照してください。エラーメッセージの詳細は以下を参照してください。
s
コマンドのサーバエラーや予期せぬネットワークの送信エラーなどの問題などに対応するために、s
コマンドが成功するまでリトライすることが有効です。その際、リングバッファなどを使ってストリーミング音源からの音声を失わないような対策を行うことでより頑健なアプリケーションを作成することができます。