Возможно воспроизведение и запись AVAudioEngine?

#swift #avaudioplayer #speech-to-text #speech #avaudioengine

#swift #avaudioplayer #преобразование речи в текст #речь #avaudioengine

Вопрос:

Я пытаюсь использовать AVAudioEngine для воспроизведения звука кнопки. Но, к сожалению, звуковой файл воспроизводится только один раз.

Идея заключается в том, что пользователь нажимает на кнопку, воспроизводится звук и начинается запись. После того, как пользователь снова нажмет на кнопку, должен зазвучать второй звук, указывающий на то, что сеанс записи завершен.

На данный момент появляется первый звук, и начинается запись. К сожалению, второй звук (завершающий звук) не воспроизводится.

И я обнаружил, что когда я использую тот же AudioEngine, что и функция записи, звук вообще не воспроизводится.

Поскольку я совершенно новичок в среде AVFoundation, я не уверен, в чем здесь проблема.

Заранее благодарю.

     var StartSoundEngineScene1 = AVAudioEngine()
    var StartSoundNodeScene1 = AVAudioPlayerNode()

    func SetupAudio(AudioEngine: AVAudioEngine, SoundNode: AVAudioPlayerNode, FileURL: URL) {
        
        guard let AudioFile = try? AVAudioFile(forReading: FileURL) else{ return }
        let AudioSession = AVAudioSession.sharedInstance()

        AudioEngine.attach(SoundNode)
        AudioEngine.connect(SoundNode, to: AudioEngine.mainMixerNode, format: AudioFile.processingFormat)
        AudioEngine.prepare()
        
    }

   override func viewDidLoad() {
        super.viewDidLoad()
        
        SetupAudio(AudioEngine: StartSoundEngineScene1, SoundNode: StartSoundNodeScene1, FileURL: StartRecSound)

}

  
 
    func ButtonSound (AudioEngine: AVAudioEngine, SoundNode: AVAudioPlayerNode, FileURL: URL){
        
        try? AudioEngine.start()
        
        guard let audioFile = try? AVAudioFile(forReading: FileURL) else{ return }
        
        SoundNode.scheduleFile(audioFile, at: nil, completionHandler: nil)
        SoundNode.volume = 0.16
        SoundNode.play()
                
    }

func StartRecording(){
        
ButtonSound(AudioEngine: StartSoundEngineScene1, SoundNode: StartSoundNodeScene1, FileURL: StartRecSound)

Timer.scheduledTimer(withTimeInterval: 0.7, repeats: false) { timer in

          if audioEngine.isRunning {
                audioEngine.stop()
                recognitionRequest?.endAudio()
            
          } else {
              print("Rercording Started")
                  
              if let recognitionTask = self.recognitionTask {
                  recognitionTask.cancel()
                  self.recognitionTask = nil
              }
              
              self.recordedMessage = ""
              
              let audioSession = AVAudioSession.sharedInstance()
              do {
                try audioSession.setCategory(AVAudioSession.Category.record)
                try audioSession.setMode(AVAudioSession.Mode.measurement)
              }catch {
                  print(error)
              }
                        
              recognitionRequest = SFSpeechAudioBufferRecognitionRequest()
              
              guard let recognitionRequest = self.recognitionRequest else {
                  fatalError("Unable to create a speech audio buffer")
              }
              
              recognitionRequest.shouldReportPartialResults = true
              recognitionRequest.requiresOnDeviceRecognition = true
                  
              recognitionTask = speechRecognizer?.recognitionTask(with: recognitionRequest, resultHandler: { (result, error) in
                  
                  var isFinal = false
                  if let result = result {
                      let sentence = result.bestTranscription.formattedString
                      self.recordedMessage = sentence
                      print (self.recordedMessage)
                      isFinal = result.isFinal
                  }
                  
                  if error != nil || isFinal {
                      self.audioEngine.stop()
                      self.audioEngine.inputNode.removeTap(onBus: 0)
                      self.recognitionRequest = nil
                      self.recognitionTask = nil
                      self.RecordBtn.isEnabled = true
                  }
                  
              })
              
              let recordingFormat = audioEngine.inputNode.outputFormat(forBus: 0)
              audioEngine.inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer, when) in
                  self.recognitionRequest?.append(buffer)
              }
              
              audioEngine.prepare()
                
              do{
                  try audioEngine.start()
              }catch {
                  print(error)
              }
          }
      }

}
    
    func StopRecording(){
         if audioEngine.isRunning{
             audioEngine.stop()
ButtonSound(AudioEngine: StartSoundEngineScene1, SoundNode: StartSoundNodeScene1, FileURL: StopRecSound)
             recognitionRequest?.endAudio()
             audioEngine.inputNode.removeTap(onBus: 0)
             }
         }

  

Ответ №1:

Вы устанавливаете категорию AVAudioSessionCategory в качестве записи.

 try audioSession.setCategory(AVAudioSession.Category.record)
  

Если вы хотите воспроизводить и записывать одновременно, вам следует установить эту категорию playAndRecord

И… Если вы измените AVAudioSession во время воспроизведения или записи, конфигурация AVAudioEngine будет изменена, после чего появится уведомление AVAudioEngineConfigurationChange.