iOS 語(yǔ)音識(shí)別

2019-10-21 17.04.38.gif

文檔
Android speech
iOS speech

權(quán)限

權(quán)限.png

開(kāi)始錄音

#pragma mark - 開(kāi)始錄音
- (void)startRecording{
    
    [self.audioEngine stop];
    if (_recognitionRequest) {
        [_recognitionRequest endAudio];
    }
    
    
    if (_recognitionTask) {
        [_recognitionTask cancel];
        _recognitionTask = nil;
    }
    
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    NSError *error;
    [audioSession setCategory:AVAudioSessionCategoryRecord error:&error];
    NSParameterAssert(!error);
    [audioSession setMode:AVAudioSessionModeMeasurement error:&error];
    NSParameterAssert(!error);
    [audioSession setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:&error];
    NSParameterAssert(!error);
    
    if (@available(iOS 10.0, *)) {
        _recognitionRequest = [[SFSpeechAudioBufferRecognitionRequest alloc] init];
    } else {
        // Fallback on earlier versions
    }
    AVAudioInputNode *inputNode = self.audioEngine.inputNode;
    NSAssert(inputNode, @"錄入設(shè)備沒(méi)有準(zhǔn)備好");
    NSAssert(_recognitionRequest, @"請(qǐng)求初始化失敗");
    _recognitionRequest.shouldReportPartialResults = YES;
    __weak typeof(self) weakSelf = self;
    if (@available(iOS 10.0, *)) {
        
        _recognitionTask = [self.speechRecognizer recognitionTaskWithRequest:_recognitionRequest resultHandler:^(SFSpeechRecognitionResult * _Nullable result, NSError * _Nullable error) {
            __strong typeof(weakSelf) strongSelf = weakSelf;
            BOOL isFinal = NO;
            if (result) {
                NSString  *resultString = result.bestTranscription.formattedString;
                NSLog(@"resultString=%@",resultString);
                if(resultString.length>0){
                    self.resultString=resultString;
                    self.viewTalk.resultString=self.resultString;
                }
                isFinal = result.isFinal;
                //[strongSelf.viewTalk.threeWave changeAnimate];
            }
            if (error || isFinal) {
                [self.audioEngine stop];
                [inputNode removeTapOnBus:0];
                strongSelf.recognitionTask = nil;
                strongSelf.recognitionRequest = nil;
                NSLog(@"(error || isFinal)=%@",error);
            }
            
        }];
    } else {
        // Fallback on earlier versions
    }
    
    AVAudioFormat *recordingFormat = [inputNode outputFormatForBus:0];
    //在添加tap之前先移除上一個(gè)  不然有可能報(bào)"Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio',"之類(lèi)的錯(cuò)誤
    [inputNode removeTapOnBus:0];
    [inputNode installTapOnBus:0 bufferSize:1024 format:recordingFormat block:^(AVAudioPCMBuffer * _Nonnull buffer, AVAudioTime * _Nonnull when) {
        __strong typeof(weakSelf) strongSelf = weakSelf;
        if (strongSelf.recognitionRequest) {
            [strongSelf.recognitionRequest appendAudioPCMBuffer:buffer];
        }
    }];
    
    [self.audioEngine prepare];
    [self.audioEngine startAndReturnError:&error];
    NSParameterAssert(!error);
}

結(jié)束錄音

#pragma mark - 結(jié)束錄音
- (void)endRecording{
    [self.audioEngine stop];
    if (_recognitionRequest) {
        [_recognitionRequest endAudio];
    }
    
    if (_recognitionTask) {
        [_recognitionTask cancel];
        _recognitionTask = nil;
    }
}

識(shí)別代理

#pragma mark - SFSpeechRecognizerDelegate  識(shí)別代理
- (void)speechRecognizer:(SFSpeechRecognizer *)speechRecognizer availabilityDidChange:(BOOL)available API_AVAILABLE(ios(10.0)){
    if (available) {
        NSLog(@"delegate :開(kāi)始錄音");
    }
    else{
        NSLog(@"語(yǔ)音識(shí)別不可用");
    }
}

??然而需要注意的卻是出發(fā)錄音和結(jié)束錄音的方法調(diào)用:保證從開(kāi)始到結(jié)束整個(gè)過(guò)程,各自只能調(diào)用一次。

#pragma warning - 保證整個(gè)過(guò)程,兩個(gè)代理各自只能調(diào)用一次
- (void)longPress:(UILongPressGestureRecognizer *)gestureRecognizer {
    
    if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
    
        [self buttonTouchDown];
    } else if(gestureRecognizer.state == UIGestureRecognizerStateChanged) {
        /*
        NSLog(@"手勢(shì)位置發(fā)生變化");
        CGPoint point = [gestureRecognizer locationInView:self];
        if (![self.layer containsPoint:point]) {
            [self buttonTouchCancel];
        }
         */
    } else if (gestureRecognizer.state == UIGestureRecognizerStateEnded){
        //NSLog(@"結(jié)束手勢(shì)事件");
        [self buttonTouchCancel];
    } else if (gestureRecognizer.state == UIGestureRecognizerStateFailed){
        //NSLog(@"無(wú)法識(shí)別的手勢(shì)");
    }
}

具體demo放這了--

----end.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容