LoginSignup
9
7

More than 3 years have passed since last update.

UnityでMicrosoft Cognitive Speech Servicesによる音声認識をAndroidスマホで実装する

Last updated at Posted at 2020-02-10

Androidスマホで動作するUnityの3Dアプリに音声認識をさせる必要が生じたので、簡単なサンプルを作るところから始めました。音声認識には「Microsoft Cognitive Speech Services」を使うことにしました。ちょっとハマったので、備忘録も兼ねて書いておきます。

開発環境

Windows 10
Unity Ver 2019.2.17f1
Android 9.0 (Galaxy Note9)

(1)Microsoft Cognitive Speech Servicesの準備

Microsoft Azure の無料アカウントを作成

まず、Microsoft Azure の無料アカウントを作ります。ちょっと古いけど、この辺が参考になると思います。
Microsoft Azure の無料アカウントを作ってみた

Cognitive Servicesのプロジェクトを作る

Azure Cognitive ServicesのSpeech to Textで書き起こしをしてみよう」の「Cognitive Servicesのプロジェクトを作る」を参考にします。
ただし、「S0」で作っているけど、無料の「F0」がいいと思います。Nameは、これから作るプロジェクトに合わせて「csharp-unity」にしておきます。

(2) Unity 用 Speech SDKのインストール

クイック スタート:開発環境を設定する」を参考に、Unity 用 Speech SDKをダウンロードします。パッケージのインポートはプロジェクトを作ってからやるので、とりあえずダウンロードだけでOKです。

(3) Unityでプロジェクトを作成する

クイック スタート:マイクから音声を認識する」を参考にUnityのプロジェクトを作ります。

サイトの、「サンプル コードを追加する」項目の「5. YourSubscriptionKey という文字列を探し、実際の Speech サービスのサブスクリプション キーに置き換えます。」で使うキーは(1)で作ったKey1をコピーします。また、リージョンは「東日本」を選んでいれば「japaneast」になります。

プロジェクトを作ったら、上記「(2) Unity 用 Speech SDKのインストール」でダウンロードした「Speech SDK」をダブルクリックして展開し、「import」します。
image.png

(4) PCで実行確認

とりあえず、PCで実行確認すると、ちゃんとSpeech Serviceが機能して音声入力できました。
image.png

(5) Android端末で実行確認(失敗)

ここでハマりました。「connection failed (no connection to the remote host)・・・」なんてエラーが出ます。
image.png

要はこのプログラムはインターネットのアクセス許可がないようです。Androidで動かしているので、とりあえずAndroidManifestを探します。ファイル検索すると「temp」の中にありました。開いてみるとインターネット許可のパーミッションがありません。
Unity ドキュメントのAndroid マニフェストの説明」によると、「Unity は適切なマニフェストを生成しますが、そのコンテンツを直接制御したい場合もあるでしょう。Unity 以外で作成した Android マニフェストを使用するには、以下の場所にその Android マニフェストファイルを置いてください。 Assets/Plugins/Android/AndroidManifest.xml 。こうすることによって、デフォルトの Unity が作成したマニフェストをオーバーライドすることができます。」とあるので、「csharp-unity\Temp\StagingArea」の中にあったAndroidManifest.xmlをコピーして
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

を追加してみましたが駄目でした。

でも、このページを再度読むと、
「パーミッション
Unityは、Android Player 設定と、アプリケーションがスクリプトから呼び出す Unity API に基づいて、マニフェストに必要なパーミッションを自動的に加えます。以下はその例です。
・Network クラスにより INTERNET パーミッションを加えます。」
とあります。つまり、「Network クラスのメソッドをなんか使えばいいんじゃね?」ということで、HelloWorld.csの62行目あたりを次のように編集してみました。

HelloWorld.csの62行目あたり
else if (result.Reason == ResultReason.Canceled)
{
   var internet = Application.internetReachability;

   var cancellation = CancellationDetails.FromResult(result);
   newMessage = $"CANCELED: Reason={cancellation.Reason} ErrorDetails={cancellation.ErrorDetails} {internet}";
}

(6) Android端末で実行確認(成功)

今度は無事に動きました。めでたし、めでたし。

image.png

9
7
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7