iOS 10のSpeech.framework


復習


次の会議は別の革新です。 気分から判断すると、キーボードと入力デバイスのキャンセルを待っています。 iOS 10のAppleは、開発者にスピーチを扱う機会をもたらしました。 私の同僚のGeor Casapidi彼の記事でSiriの機能について既に説明しているので、 Speech.frameworkについてお話します。 この記事で説明した資料は、what_i_sayデモアプリケーションに実装されています。 執筆時点では、公式文書はありませんので、 ヘンリー・メイソンの話に基づいています。


音声の処理はインターネットへのアクセスと完全に結びついていますが、同じSiriエンジンが使用されているため、これは驚くことではありません。 開発者には、ライブスピーチを認識するか、既にファイルに記録されているかのいずれかの機会が与えられます。 リクエストオブジェクトの違い:


SFSpeechURLRecognitionRequestファイルからの認識に使用。
SFSpeechAudioBufferRecognitionRequestディクテーションを認識するために使用されます。


リアルタイムのディクテーションを使用することを検討してください。


すべての作業は、回路図に基づいています。



ただし、Speech.frameworkには特別なマイクAPIが含まれていないため、開発者はAVAudioEngineを使用する必要があります。


申請承認


最初に、開発者はInfo.plistファイルに2つのキーを追加する必要があります


NSMicrophoneUsageDescriptionマイクにアクセスする理由
NSSpeechRecognitionUsageDescription音声認識へのアクセスが必要な理由



これらがなければ避けられないクラッシュが発生するため、これは重要です。


次に、承認ステータスを処理する必要があります。


 - (void)handleAuthorizationStatus:(SFSpeechRecognizerAuthorizationStatus)s { switch (s) { case SFSpeechRecognizerAuthorizationStatusNotDetermined: //        [self requestAuthorization]; break; case SFSpeechRecognizerAuthorizationStatusDenied: //    [self informDelegateErrorType:(EVASpeechManagerErrorSpeechRecognitionDenied)]; break; case SFSpeechRecognizerAuthorizationStatusRestricted: //   break; case SFSpeechRecognizerAuthorizationStatusAuthorized: { //   } break; } } 

Speech.frameworkを理解する段階では、 SFSpeechRecognizerAuthorizationStatusRestrictedのステータスを使用するユースケースを見つけることができませんSFSpeechRecognizerAuthorizationStatusRestricted 。 このステータスは制限されたアクセス権の下で計画されたと思いますが、今のところ音声認識の追加オプションはありません。 さて、公式のドキュメントを待ちます。



インストール後のアプリケーションの最初の起動時に、 SFSpeechRecognizerAuthorizationStatusNotDeterminedSFSpeechRecognizerAuthorizationStatusNotDeterminedのステータスをSFSpeechRecognizerAuthorizationStatusNotDeterminedため、ユーザーに認証を要求する必要があります。


 - (void)requestAuthorization { [SFSpeechRecognizer requestAuthorization:^(SFSpeechRecognizerAuthorizationStatus status) { [self handleAuthorizationStatus:status]; }]; } 

APIには、ステータスの変更を追跡するためのメソッドや通知はありません。 ユーザーが認証状態を変更すると、システムはアプリケーションを強制的に再起動します。


カスタマイズ


音声認識を成功させるには、4つのオブジェクトが必要です。


 @property (nonatomic, strong) SFSpeechRecognizer *recognizer; @property (nonatomic, strong) AVAudioEngine *audioEngine; @property (nonatomic, strong) SFSpeechAudioBufferRecognitionRequest *request; @property (nonatomic, strong) SFSpeechRecognitionTask *currentTask; 

プロトコルを実装します。


 @interface EVASpeechManager () <SFSpeechRecognitionTaskDelegate> 

recognizer -リクエストを処理するオブジェクト。
重要なことから:



ro-RO en-IN he-IL tr-TR en-NZ sv-SE fr-BE it-CH de-CH pl-PL pt-PT uk-UA fi-fi vi-VN ar-SA zh-TW es- ES en-GB yue-CN th-TH en-ID ja-JP en-SA en-AE da-DK fr-FR sk-SK de-AT ms-MY hu-HU ca-ES ko-KR fr-CH nb -NO en-AU el-GR ru-RU zh-CN en-US en-IE nl-BE es-CO pt-BR es-US hr-HR fr-CA zh-HK es-MX id-ID it-IT nl-NL cs-CZ en-ZA es-CL en-PH en-CA en-SG de-DE

認識エンジンはロケールを自動的に切り替えません。 初期化中に定義されたロケール内で機能します。 つまり 初期化がen-USロケールであり、ユーザーが別の言語を話す場合、認識エンジンは動作して空の回答を返します。



audioEngineマイクからの入力信号(音声入力)と出力信号をバッファーに接続するオブジェクト。


  self.audioEngine = [[AVAudioEngine alloc] init]; AVAudioInputNode *node = self.audioEngine.inputNode; AVAudioFormat *recordingFormat = [node outputFormatForBus:bus]; [node installTapOnBus:0 bufferSize:1024 format:recordingFormat block:^(AVAudioPCMBuffer * _Nonnull buffer, AVAudioTime * _Nonnull when) { [self.request appendAudioPCMBuffer:buffer]; }]; 

request -音声認識のリクエスト。
興味深いから:



説明によれば、要求をタイプ、つまり通常のディクテーション、情報を検索するディクテーション、何かを確認するディクテーションにタイプを分割することが計画されていると想定できます。 残念ながら、現在はマーカーとして以外、どこでも使用されていません。 このリンクの開発があると思います。


currentTask -1つの要求を処理するためのタスクオブジェクト。
重要なことから:



使用する


打ち上げ


スピーチマネージャを正常にセットアップしたら、作業自体に進むことができます。
リクエストを作成する必要があります。


 self.request = [[SFSpeechAudioBufferRecognitionRequest alloc] init]; 

それをリゾルバに渡します:


重要! 認識audioEngineにリクエストをaudioEngineaudioEngineをアクティブにして、マイクからオーディオストリームを受信する必要があります。

 - (void)performRecognize { [self.audioEngine prepare]; NSError *error = nil; if ([self.audioEngine startAndReturnError:&error]) { self.currentTask = [self.recognizer recognitionTaskWithRequest:self.request delegate:self]; } else { [self informDelegateError:error]; } } 

リクエストを受け入れると、システムはタスクオブジェクトを返します。 後でプロセスを停止する必要があります。


やめて


要求オブジェクトは、アクティブな間は再利用できません。そうしないと、 “reason: 'SFSpeechAudioBufferRecognitionRequest cannot be re-used'”というクラッシュが発生します。 したがって、プロセスの最後にタスクとaudioEngineを停止することが重要です。


 - (void)stopRecognize { if ([self isTaskInProgress]) { [self.currentTask finish]; [self.audioEngine stop]; } } 

結果処理


タスクの最後に、結果がSFSpeechRecognitionTaskDelegateデリゲートSFSpeechRecognitionTaskDelegate配信されSFSpeechRecognitionTaskDelegate


メソッドで認識されたテキストを処理できます:


 - (void)speechRecognitionTask:(SFSpeechRecognitionTask *)task didFinishRecognition:(SFSpeechRecognitionResult *)recognitionResult { self.buffer = recognitionResult.bestTranscription.formattedString; } 

メソッドのエラー:


 - (void)speechRecognitionTask:(SFSpeechRecognitionTask *)task didFinishSuccessfully:(BOOL)successfully { if (!successfully) { [self informDelegateError:task.error]; } else { [self.delegate manager:self didRecognizeText:[self.buffer copy]]; } } 

間違い


アプリケーションの操作中にエラーが発生しました:


エラー:SessionId=com.siri.cortex.ace.speech.session.event.SpeechSessionId@439e90ed、メッセージ= 30000ミリ秒後にコマンドを待つタイムアウト

エラー:SessionId=com.siri.cortex.ace.speech.session.event.SpeechSessionId@714a717a、メッセージ=空の認識

最初のエラーは、少し口述した後、スピーチが終了し(ユーザーが話をやめた)、認識エンジンが動作し続けたときに発生しました。


2番目のエラーは、認識エンジンがオーディオストリームを受信せず、ユーザーによってプロセスがキャンセルされた場合です。


両方のエラーがデリゲートメソッドでキャッチされました。


 - (void)speechRecognitionTask:(SFSpeechRecognitionTask *)task didFinishSuccessfully:(BOOL)successfully { if (!successfully) { //     task.error } } 

おわりに


Speech.frameworkを初めて知った後、彼がまだ「生」であることが明らかになりました。 多くのことを完成させてテストする必要があります。 初めは悪くない、情報を入力する手段のない人工知能と仕事への欲求がある。 IoTと組み合わせることで、ガジェット、家、車を管理する大きな機会が開かれます。 それまでの間、待って、訓練し、さらに探索してください。


参照資料




Source: https://habr.com/ru/post/J304714/


All Articles