メジャーアップデートしたXamarin.iOSでiOS 10のアプリ(翻訳アプリ)を作ってみた
1 はじめに
iOS 10やXcode 8が公開された9月14日と同じ日に、Xamarinもメジャーアップデートされました。
Xamarin.iOSは、10.0となり、iOS10対応、Xamarin.Android 7.0となり、Android 7.0 Nougatに対応しています。
今回は、この新しいXamarin.iOSで、iOS 10 のSDKで新たに追加されたSpeech APIを使用して、簡単な翻訳アプリを作成してみました。
本アプリで利用させて頂いたフレームワーク等は、次のとおりです。
- 音声入力 SFSpeechRecognizer
- 翻訳 Microsoft Translator
- 読み上げ AVFoundation
2 実行画面
実際に動作している画面です。
一番左が起動時の状態です。そして、「開始」ボタンを話しかけると、入力が上の欄に表示されます。 続いて、「翻訳」のボタンを押すと、翻訳されたものが下の段に表示され、同時に読み上げられます。
3 実装
(1) プロジェクト作成
メニューから、File > New Solution > iOS > App > Single View Appd と辿り、新しいソリューションを作成します。(ここでは、名前をXamarin.iOS.SpeechRecognizerSampleとしました)
(2) ストーリーボード
ストーリーボードを使用して、2つのUITextViewと、1つのUIButtonを配置し、それぞれInputTextView、OutputTextView、OperationButtonと名前を指定しました。
Xamarin.iOSでは、コントロールに名前を指定するだけで、ビューコントローラー名.designer.csにプロパティが自動で作成され、これを通して操作可能になります。
(4) 追加パッケージ
Add PackeagesからSystem.Net.HttpとJson.NETを追加しました。
また、Edit Refelencesから System.Xml.Ling を追加しました。
4 音声入力(SFSpeechRecognizer)
音声入力には、SFSpeechRecognizerを使用しました。
SFSpeechRecognizerは、リアルタイム音声及び、録音済み音声に対応していますが、今回利用したのはリアルタイム音声による入力です。 リアルタイム音声を利用する場合の作業は、概ね次のとおりです。
- ユーザの許可(info.plist)
- マイク利用(AVAudioEngine)
- SFSpeechRecognizerの生成
- リクエストの作成
- リクエストの開始とデータ取得
(1) ユーザの許可(info.plist)
info.plistに下記の2つの設定を追加し、ユーザからの許可を得ます。
- NSMicrophoneUsageDescription(マイクの用途について)
- NSSpeechRecognitionUsageDescription(音声認識の用途について)
設定を追加するには、info.plitsをダブルクリックして開き、Sourceをタブを選択します。
Add New Entryをクリックして、新しい行を追加し、キーとその用途を設定します。
ユーザへの許可は、実行時に次のように表示されます。
(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万文字まで無料で利用可能です。
翻訳ボタンを押した時点で、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を一旦閉じると、次に開けた時に真っ白になって慌てました。 一度、表示デバイスの種類を変更すると、正常に表示されました。
8 最後に
今回は、Xamarinの最新版で、iOS 10用のアプリを作成してみました。 iOSの更新に、追いつくというより、同日に公開されてしまう、Xamarinが相変わらず凄いと思います。
次回は、XamarinでSiriKitを書いてみたいと考えています。
コードは下記に置きました。気になるところが有りましたら、ぜひ教えてやってください。
[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 機械翻訳