WatsonのSpeech To TextをXamarin.Formsで試してみたよ('◇')ゞ
音声認識の実装に関して興味があったのでWatsonのSpeech To Textを使用してXamarin.Fromsで音声認識を行ってみました。
なぜWatsonにしたか
GooleのCloud Speech APIが50回の回数制限があったから。
です。
Xamarin.Formsで音声入力を文字化する実装を考えたときにAndroidの方はSpeechRecognizerを使用すればできるんですが
iOSの方がなかなか難しいんです。
最初はGoogle Cloud Speech APIを使って音声認識を試してみようかと思ったのですが使用回数が50/dayだったりでほんとにちょっとしたテストしかできませんでした。
ということで別の方法を探してました。
この記事を読んでいたら
Watsonは有料となっていたのですがサイトを見てみたら最初の1000分までは無料とのことだったので試すにはちょうど良いと思いWatsonを試してみました。
CMとかもやってますしねぇ。Watson。
登録とか
Bluemixのアカウントを作成します。
最初の30日は無料ですべてのサービスにアクセスできるみたいです。
Bluemixのアカウントを作成すると組織とスペースを決めます。
組織は日本語で大丈夫でしたがスペースは日本語だめかもしれません。
最初に日本語を入れてみたのですが、登録は成功するけど反映されないみたいなおかしな状態になったので英語にしたほうが良いかと思います。
ホーム画面からWatsonを選択します。
右上の「+」ボタンをクリックします。
Speech To Textを選択します。
特に考えずに作成を行います。
資格情報の作成を行います。
usernameとpasswordは認証情報として使用します。
APIについて
APIReferenceはちゃんと用意されています。
主にHTTPを使用したセッションありとセッションなしのAPI、WebSocketを使用したAPIがあります。
HTTPを使用したセッションは保存済みのデータをテキストに変換するのに適していてWebSocketはリアルタイムに変換する事に向いていると考えてよいかと思います。
Java用とnode.js用のライブラリは用意されています。
またUnity用のC#ライブラリもありますので、お手軽にっていうのであればそちらを利用するのも手です。
今回はAPIの理解を得たい面もあったのでそれらは使用せずに実装します。
リアルタイム変換を行いたいのでWebSocketのAPIをします。
実装
とりあえずソースコードを
Observer/Observableパターンで実装してます。
使用しているライブラリは
WebSocket-Sharp
Json.NET
認証
まずWebSocketで接続を行います。
接続URLはwss://stream.watsonplatform.net/speech-to-text/api/v1/recognize
クエリストリングにてmodelを指定できます。
modelは言語に使用する言語に対応した物を指定します。
今回は日本語ですのでja-JP_BroadbandModel
を使います。
資格情報としてSpeechToTextの資格情報を設定します。
_client.SetCredentials(user, password, true);
そして接続を行います。
接続に成功した場合、クライアントからスタート情報をjsonで送信することで変換ストリーミングを開始できます。
var startjson = JsonConvert.SerializeObject( new Connection { Action = "start", content_Type = $"audio/l16;rate={SampleRate};channels={Channel}", InterimResults = InterimResults, Continuous = Continuous, InactivityTimeout = -1, MaxAlternatives = 1, Timestamps = false, WordConfidence = false }, Formatting.Indented); Debug.WriteLine(startjson); _client.Send(startjson); _isSending = true;
今回はPCM音声データを使用しますのでcontent-typeにはl16を指定しrateとchannelsを追加で指定します。
Interim_resultsは変換が確定しない時点でもストリーミング的に途中結果を受け取ることができます。
continuousを有効にすることで断続した変換を行うことができます。
スタート要求を送信するとstate : "listening"というjsonを返答してくれます。
スタートを送信したらあとは、PCMデータをWebSocketのBinaryFrameにて送信することで結果を返答してくれます。
if (!_isConnected) return; if (value.IsStop == false) { if (!_isSending) { StartRecognize(); } _client.Send(value.PcmStream); } else { _client.Send("{\"Action\": \"stop\"}"); _isSending = false; Debug.WriteLine("Stop"); }
結果に関しては Speech to Text Service Documentation | Watson Developer Cloudを読んでください。
受信処理は
var result = JsonConvert.DeserializeObject<SpeechResult>(args.Data); Debug.WriteLine(args.Data); result.Results.ForEach(res => { if (res.Alternatives.Any()) { var speechtext = new SpeechText { IsFainel = res.Final, Text = res.Alternatives.First().Transcript }; _speechTextSubject.OnNext(speechtext); } });
こんな感じで書くことができます。
今回はXamarin.Forms側のプログラムは説明しませんがソースコードは
こちらで確認することができます。
精度的には他と比較していないので何ともです。
おそらく多と比較検討してくれる記事などを書いてくれる人が出てくると思うので期待です。
このように実装することでオンライン限定ですがクロスプラットフォームでの音声認識を実装できます。
このケースでは音声認識部分はAndroidとiOSでコード共有率100パーセントです。
Xamarin素晴らしい。
以上です。