メジャーアップデートしたXamarin.iOSでiOS 10のアプリ(翻訳アプリ)を作ってみた

Xamarin

1 はじめに

iOS 10やXcode 8が公開された9月14日と同じ日に、Xamarinもメジャーアップデートされました。

Xamarin.iOSは、10.0となり、iOS10対応、Xamarin.Android 7.0となり、Android 7.0 Nougatに対応しています。

001

今回は、この新しいXamarin.iOSで、iOS 10 のSDKで新たに追加されたSpeech APIを使用して、簡単な翻訳アプリを作成してみました。

本アプリで利用させて頂いたフレームワーク等は、次のとおりです。

  • 音声入力 SFSpeechRecognizer
  • 翻訳 Microsoft Translator
  • 読み上げ AVFoundation

2 実行画面

実際に動作している画面です。

一番左が起動時の状態です。そして、「開始」ボタンを話しかけると、入力が上の欄に表示されます。 続いて、「翻訳」のボタンを押すと、翻訳されたものが下の段に表示され、同時に読み上げられます。

こちらに動画も有りますので、是非、ご覧ください

015 013 014

3 実装

(1) プロジェクト作成

メニューから、File > New Solution > iOS > App > Single View Appd と辿り、新しいソリューションを作成します。(ここでは、名前をXamarin.iOS.SpeechRecognizerSampleとしました)

002

(2) ストーリーボード

ストーリーボードを使用して、2つのUITextViewと、1つのUIButtonを配置し、それぞれInputTextViewOutputTextViewOperationButtonと名前を指定しました。

003

Xamarin.iOSでは、コントロールに名前を指定するだけで、ビューコントローラー名.designer.csにプロパティが自動で作成され、これを通して操作可能になります。

004

(4) 追加パッケージ

Add PackeagesからSystem.Net.HttpJson.NETを追加しました。

009

また、Edit Refelencesから System.Xml.Ling を追加しました。

010

4 音声入力(SFSpeechRecognizer)

音声入力には、SFSpeechRecognizerを使用しました。

SFSpeechRecognizerは、リアルタイム音声及び、録音済み音声に対応していますが、今回利用したのはリアルタイム音声による入力です。 リアルタイム音声を利用する場合の作業は、概ね次のとおりです。

  • ユーザの許可(info.plist)
  • マイク利用(AVAudioEngine)
  • SFSpeechRecognizerの生成
  • リクエストの作成
  • リクエストの開始とデータ取得

(1) ユーザの許可(info.plist)

info.plistに下記の2つの設定を追加し、ユーザからの許可を得ます。

  • NSMicrophoneUsageDescription(マイクの用途について)
  • NSSpeechRecognitionUsageDescription(音声認識の用途について)

設定を追加するには、info.plitsをダブルクリックして開き、Sourceをタブを選択します。

005

Add New Entryをクリックして、新しい行を追加し、キーとその用途を設定します。

006 ユーザへの許可は、実行時に次のように表示されます。

011 012

(2) マイクの利用(AVAudioEngine)

マイクの利用には、AVAudioEngineを使用します。 利用の方法は、概ね次のとおりです。

// 生成
var audioEngine = new AVAudioEngine();

// 停止
audioEngine.Stop();

// 開始
audioEngine.Prepare();
audioEngine.StartAndReturnError(out err);

// 入力をSFSpeechRecognizerに送る 
var inputNode = audioEngine.InputNode;
var recordingFormat = inputNode.GetBusOutputFormat(0);
inputNode.InstallTapOnBus(0, 1024, recordingFormat, (buffer, when) =>
{
    recognitionRequest?.Append(buffer);
});

(3) SFSpeechRecognizerの作成

ロケールを指定してSFSpeechRecognizerを作成します。

var speechRecognizer = new SFSpeechRecognizer(new NSLocale("ja-JP"));

(4) リクエストの作成

マイク等のオーディオバッファを利用する場合は、SFSpeechAudioBufferRecognitionRequestを使用します。

var recognitionRequest = new SFSpeechAudioBufferRecognitionRequest
{
    ShouldReportPartialResults = true
};

(5) リクエストの開始とデータ取得

recognitionTaskでリクエストを開始してクロージャーで入力を取得します。 入力に変化があるたびに、開始後の全部の文字列が返されます。

recognitionTask = speechRecognizer.GetRecognitionTask(recognitionRequest, (result, error) =>
{
    if (result != null)
    {
        if (mode == Mode.Recording)
        {
            inputTextView.Text = result.BestTranscription.FormattedString;

        }
    }
}

以上、簡単に列挙しましたが、詳しくは、サンプルコードご参照下さい。

5 翻訳

翻訳については、Microsoft Translatorを利用させて頂きました。(とりあえず無料枠がある翻訳サービスは、今、これしかないと思います)

同サービスは、1ヶ月あたり200万文字まで無料で利用可能です。

003

翻訳ボタンを押した時点で、SFSpeechRecognizerの出力したテキストを同サービスで翻訳して下の段に表示しています。

本サービスについては、下記で紹介させて頂いております。詳しい使い方については、こちらをご参照下さい。
Xamarin.Forms 機械翻訳
[iOS] 翻訳機能付Twitterクライアント

6 読み上げ

読み上げには、AVFoundationを使用しました。

使い方は、非常に簡単です。

var speechSynthesizer = new AVSpeechSynthesizer();
var speechUtterance = new AVSpeechUtterance(str)
{
    Voice = AVSpeechSynthesisVoice.FromLanguage("en"),
    Volume = 1.0f,
};
speechSynthesizer.SpeakUtterance(speechUtterance);

本アプリでは、翻訳が完了した時点で、直ちに読み上げを行っています。

なお、読み上げの際は、音声入力で使用していた、AVAudioSessionの設定変更を忘れないようにして下さい。

var audioSession = AVAudioSession.SharedInstance();
audioSession.SetCategory(AVAudioSessionCategory.Ambient);

AVFoundationについての詳しい情報は、下記をご参照下さい。
[Swift] AVSpeechSynthesizerで読み上げ機能を使ってみる

7 StoryBoardが真っ白

バグってます。Storyboardを一旦閉じると、次に開けた時に真っ白になって慌てました。 一度、表示デバイスの種類を変更すると、正常に表示されました。

007 008

8 最後に

今回は、Xamarinの最新版で、iOS 10用のアプリを作成してみました。 iOSの更新に、追いつくというより、同日に公開されてしまう、Xamarinが相変わらず凄いと思います。

次回は、XamarinでSiriKitを書いてみたいと考えています。

コードは下記に置きました。気になるところが有りましたら、ぜひ教えてやってください。
github [GitHub] https://github.com/furuya02/Xamarin.iOS.SpeechRecognizerSample
※本サンプルを動作させるためには、翻訳サービスのキーが必要です。各自で別途ご用意下さい。

9 参考リンク


Introduction to iOS 10
Samples iOS 10 SpeakToMe
Introduction to Speech Recognition
SpeakToMe: Using Speech Recognition with AVAudioEngine
API Reference SFSpeechRecognizer
【iOS 10】SFSpeechRecognizerで音声認識を試してみた
[Swift] AVSpeechSynthesizerで読み上げ機能を使ってみる
Xamarin記事一覧(SAPPOROWORKSの覚書)
[Developers.IO] Xamarinシリーズ
Xamarin.Forms 機械翻訳

  • mono0926

    > vae recognitionRequest = new SFSpeechAudioBufferRecognitionRequest

    vaeはvarのタイポでしょうか?

    > SFSpeechRecognizer speechRecognizer = new SFSpeechRecognizer(new NSLocale(“ja-JP”));

    また、こちらは型推論のvarを使わずにSFSpeechRecognizerで宣言していて、書き方の揺れが気になりました。
    (好みはあるでしょうが、SFSpeechAudioBufferRecognitionRequestはvarを使っているので、そうであればこちらも揃えるべきかと思いました。)

  • SIN

    ありがとうございます。修正させて頂きました。
    ご指摘に感謝申し上げます。