Добавьте функцию, чтобы остановить распознавание голоса, чтобы голос не был слышен в течение n секунд в аудио API для iOS - PullRequest
0 голосов
/ 20 октября 2018

Я создаю приложение, используя IOS Speech API с нативным плагином Unity.

Swift: остановить распознавание речи после x секунд молчания

Я создал его, ссылаясь нана указанный выше URL, но появилась следующая ошибка.

Value of type 'SpeechRecognizer' has no member 'detectionTimer'

Что такое обнаружение времени?

Ниже приведен исходный код.

import Foundation
import UIKit
import Speech

public class SpeechRecognizer : NSObject {
    static let sharedInstance: SpeechRecognizer = SpeechRecognizer()

    private var _unitySendMessageGameObjectName: String = "SpeechRecognizer"

    var unitySendMessageGameObjectName: String {
        get {
            return _unitySendMessageGameObjectName
        }
        set {
            _unitySendMessageGameObjectName = newValue
        }
    }




    private let speechRecognizer = SFSpeechRecognizer(locale: Locale(identifier: "ja-JP"))!

    private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest?

    private var recognitionTask: SFSpeechRecognitionTask?

    private let audioEngine = AVAudioEngine()


    private override init() {
        super.init()
        speechRecognizer.delegate = self
    }



    func requestRecognizerAuthorization() {
        SFSpeechRecognizer.requestAuthorization { authStatus in
            OperationQueue.main.addOperation {
                switch authStatus {
                case .authorized:
                    self.unitySendMessage("OnAuthorized")
                    break

                case .denied:
                    // User denied access to speech recognition
                    self.unitySendMessage("OnUnauthorized")

                case .restricted:
                    // Speech recognition restricted on this device
                    self.unitySendMessage("OnUnauthorized")

                case .notDetermined:
                    // Speech recognition not yet authorized
                    self.unitySendMessage("OnUnauthorized")
                }
            }
        }
    }




    func startRecord() -> Bool {
        if audioEngine.isRunning {
            return false
        }

        try! startRecording()
        return true
    }
    func stopRecord() -> Bool {
        if !audioEngine.isRunning {
            return false
        }

        audioEngine.stop()
        recognitionRequest?.endAudio()
        return true
    }


    private func startRecording() throws {
        refreshTask()

        let audioSession = AVAudioSession.sharedInstance()
        try audioSession.setCategory(AVAudioSessionCategoryRecord)
        try audioSession.setMode(AVAudioSessionModeMeasurement)
        try audioSession.setActive(true, with: .notifyOthersOnDeactivation)


        recognitionRequest = SFSpeechAudioBufferRecognitionRequest()

        guard let inputNode = audioEngine.inputNode else { fatalError("Audio engine has no input node") }
        guard let recognitionRequest = recognitionRequest else { fatalError("Unable to created a SFSpeechAudioBufferRecognitionRequest object") }

        recognitionRequest.shouldReportPartialResults = false





        recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest) { result, error in

            var isFinal = false
            if let result = result {
                self.unitySendMessage("OnRecognized", message: result.bestTranscription.formattedString)
                isFinal = result.isFinal
                print("result\(isFinal)")
            }
            if let timer = self.detectionTimer, timer.isValid {
                if isFinal {
                    // self.unitySendMessage("OnError")
                    self.detectionTimer?.invalidate()
                }
            }
            else {
                self.detectionTimer = Timer.scheduledTimer(withTimeInterval: 1.5, repeats: false, block: { (timer) in
                    self.handleSend()
                    isFinal = true
                    timer.invalidate()
                })
            }
        }


        let recordingFormat = inputNode.outputFormat(forBus: 0)
        inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer: AVAudioPCMBuffer, when: AVAudioTime) in
            self.recognitionRequest?.append(buffer)
        }
        try startAudioEngine()
    }


    private func refreshTask() {
        if let recognitionTask = recognitionTask {
            recognitionTask.cancel()
            self.recognitionTask = nil
        }
    }


    private func startAudioEngine() throws {
        audioEngine.prepare()
        try audioEngine.start()
    }

    func unitySendMessage(_ methodName: String, message: String = "") {
        UnitySendMessage(self.unitySendMessageGameObjectName, methodName, message)
    }
}






extension SpeechRecognizer: SFSpeechRecognizerDelegate {
    public func speechRecognizer(_ speechRecognizer: SFSpeechRecognizer, 
                                 availabilityDidChange available: Bool) {
        if (available) {
            unitySendMessage("OnAvailable")
        } else {
            unitySendMessage("OnUnavailable")
        }
    }
}
...