SFSpeechRecognizer on MacOS not available despite successful authorization

与世无争的帅哥 提交于 2020-06-17 01:48:52

问题


I am trying to get a clumsy Objective-C proof-of-concept example to run with SFSpeechRecognizer on Catalina transcribing a local audio file.

After some googling I have managed to get the authorization to work by adding an Info.plist with NSSpeechRecognitionUsageDescription and I get the authorization dialog and the correct SFSpeechRecognizerAuthorizationStatus (SFSpeechRecognizerAuthorizationStatusAuthorized).

However, my SFSpeechRecognizer instance still is unavailable. I suspect, I must be making a stupid mistake due to lack of basic Objective-C knowledge.

Any hints greatly appreciated.

Here's my code:

//
//  main.m
//  SpeechTestCatalina
//

#import <Foundation/Foundation.h>
#import <Speech/Speech.h>

void transcribeTestFile(){
    NSLocale *locale =[[NSLocale alloc] initWithLocaleIdentifier:@"en-US"];
    SFSpeechRecognizer *speechRecognizer = [[SFSpeechRecognizer alloc] initWithLocale:locale];

    NSLog(@"Locale %@, %@", speechRecognizer.locale.languageCode, speechRecognizer.locale.countryCode);
    NSLog(@"Available %hhd", speechRecognizer.available);
    NSLog(@"Auth status %ld", [SFSpeechRecognizer authorizationStatus]);
    NSLog(@"Supports on device %hhd", speechRecognizer.supportsOnDeviceRecognition);
    if(speechRecognizer.isAvailable && speechRecognizer.supportsOnDeviceRecognition){
        NSString *audioFilePath = @"/Users/doe/speech-detection/speech_sample.wav";
        NSURL *url = [[NSURL alloc] initFileURLWithPath:audioFilePath];
        NSLog(@"Analyzing %@ in language %@", url, locale.languageCode);
        SFSpeechURLRecognitionRequest *urlRequest = [[SFSpeechURLRecognitionRequest alloc] initWithURL:url];
        urlRequest.requiresOnDeviceRecognition = true;
        urlRequest.shouldReportPartialResults = YES; // YES if animate writting
        [speechRecognizer recognitionTaskWithRequest: urlRequest resultHandler:  ^(SFSpeechRecognitionResult * _Nullable result, NSError * _Nullable error){
            NSString *transcriptText = result.bestTranscription.formattedString;
            if(!error){
                NSLog(@"Transcript: %@", transcriptText);
            } else {
                NSLog(@"Error: %@", error);
            }
        }];
    } else {
        NSLog(@"speechRecognizer is not available on this device");
    }
}


int main(int argc, const char * argv[]) {
    @autoreleasepool {
        [SFSpeechRecognizer requestAuthorization:^(SFSpeechRecognizerAuthorizationStatus authStatus) {
            NSLog(@"Status: %ld", (long)authStatus);
            switch (authStatus) {
                case SFSpeechRecognizerAuthorizationStatusAuthorized:
                    //User gave access to speech recognition
                    NSLog(@"Authorized");

                    transcribeTestFile();

                    break;

                case SFSpeechRecognizerAuthorizationStatusDenied:
                    //User denied access to speech recognition
                    NSLog(@"SFSpeechRecognizerAuthorizationStatusDenied");
                    break;

                case SFSpeechRecognizerAuthorizationStatusRestricted:
                    //Speech recognition restricted on this device
                    NSLog(@"SFSpeechRecognizerAuthorizationStatusRestricted");
                    break;

                case SFSpeechRecognizerAuthorizationStatusNotDetermined:
                    //Speech recognition not yet authorized

                    break;

                default:
                    NSLog(@"Default");
                    break;
            }
        }];

        NSLog(@"Sleeping");
        [NSThread sleepForTimeInterval:20.0f];

    }
    return 0;
}

The output when I run it is:

2020-01-26 17:48:39.454809+0100 SpeechTestCatalina[3623:82404] Sleeping
2020-01-26 17:48:41.182459+0100 SpeechTestCatalina[3623:82811] Status: 3
2020-01-26 17:48:41.182562+0100 SpeechTestCatalina[3623:82811] Authorized
2020-01-26 17:48:41.186933+0100 SpeechTestCatalina[3623:82811] Locale en, US
2020-01-26 17:48:41.190973+0100 SpeechTestCatalina[3623:82811] Available 0
2020-01-26 17:48:41.191269+0100 SpeechTestCatalina[3623:82811] Auth status 3
2020-01-26 17:48:41.197965+0100 SpeechTestCatalina[3623:82811] Supports on device 0
2020-01-26 17:48:41.198065+0100 SpeechTestCatalina[3623:82811] speechRecognizer is not available on this device
Program ended with exit code: 0

回答1:


You aren't getting the callback because your binary does not have a runloop. I'll take the response from this different question but with the same answer:

Callbacks in most Apple frameworks are delivered through your application's main run loop. If your command-line tool does not have a run loop, it cannot receive callbacks that are sent this way.

Without a runloop, the only way for the framework to invoke your callback would be to run it on another thread, which could lead to weird behaviour in an application that didn't expect that.

You can manually pump the runloop by inserting this code before the end of main:

NSRunLoop* runloop = [NSRunLoop currentRunLoop];
[runloop runUntilDate:[NSDate distantFuture]];

This will prevent your application from exiting; you'll need to update your logic to know when speech recognition is finished and restructure that with a while loop or something - but I assume the logic inside your "real" application is different than this toy sample.


The message:

AddInstanceForFactory: No factory registered for id F8BB1C28-BAE8-11D6-9C31-00039315CD46 HALC_ShellDriverPlugIn::Open: Can't get a pointer to the Open routine

that appears in your console a meaningless; it's some log statement leaking out of the system frameworks and you can disregard it.


Finally, for clarification on a couple other points:

  • "Enable Ask Siri" was required to be enabled in System Preferences > Siri for speech recognition to be available
  • There is a potential issue where the device may report that "on device recognition" is not available the first time you check, despite being supported for the chosen locale


来源:https://stackoverflow.com/questions/59920660/sfspeechrecognizer-on-macos-not-available-despite-successful-authorization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!