2

我正在尝试创建一个记录用户声音并同时转录它的应用程序。我正在使用 AVFoundation 和 Speech 框架来完成这项工作。问题是 Apple 将转录时间限制为一分钟。所以,在这段时间之后,我应该回忆一下语音识别请求。问题是我想同时录制声音。

有谁知道我该如何解决这个问题?

这是我正在使用的代码:

    private func startRecording() throws {

    // Cancel the previous task if it's running.
    if let recognitionTask = recognitionTask {
        recognitionTask.cancel()
        self.recognitionTask = nil
    }

    try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord, with: .allowBluetoothA2DP)
    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") }

    // Configure request so that results are returned before audio recording is finished
    recognitionRequest.shouldReportPartialResults = true

    // A recognition task represents a speech recognition session.
    // We keep a reference to the task so that it can be cancelled.
    recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest) { result, error in
        var isFinal = false

        if result != nil {

            if let result = result {
                self.textView.text = result.bestTranscription.formattedString
            }

            isFinal = (result?.isFinal)!
            if isFinal == true{
                self.textView.text.append((result?.bestTranscription.formattedString)!)
            }
        }

        if error != nil || isFinal {

            print("Error: \(error)")
            print("ifFinal: \(isFinal)")
            self.audioEngine.stop()
            inputNode.removeTap(onBus: 0)

            self.recognitionRequest = nil
            self.recognitionTask = nil

            try! self.startRecording()
            self.recordButton.isEnabled = true
            self.recordButton.setTitle("Start Recording", for: [])
        }
    }


    let recordingFormat = inputNode.outputFormat(forBus: 0)

    inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer: AVAudioPCMBuffer, when: AVAudioTime) in

        DispatchQueue.main.async {
        self.recognitionRequest?.append(buffer)
        self.writeBuffer(buffer)
        }
    }

    if !audioEngine.isRunning {
        audioEngine.prepare()
        try audioEngine.start()
    }

}

从代码中可以看出,我提出了请求,并在 installTap 方法中写入了音频文件。因此,每次我必须重新开始转录时,我还必须移除总线上的水龙头。这样,我就无法继续录制音频文件了。

有什么我可以做的吗?有什么解决办法吗?备择方案?

4

1 回答 1

0

您可以在 audioEngine 的 mainMixerNode 上安装一个水龙头来进行录音。这应该使您能够在不中断录制的情况下移除 inputNode 上的点击。

或者,只需更改 self.recognitionRequest 而不移除水龙头。原始点击应该自动将缓冲区附加到新请求。

当我尝试做同样的事情时,我能够在不中断记录的情况下启动新的识别请求。但是,我无法防止转录中的空白。似乎第一个识别请求必须在第二个可以开始之前完成,并且一些缓冲区在中间丢失了。有可能将这些缓冲区保留在内存中,直到第二个开始...

于 2017-11-01T12:20:07.563 回答