Запись буфера из AVAudioNodeTap в AVAudioFile (сохранение аудиозаписи из AVAudioEngine)

#swift #xcode #avaudioengine #avkit

#swift #xcode #avaudioengine #avkit

Вопрос:

Я использую AVAudioEngine для мониторинга микрофонного входа. После остановки AudioEngine я хотел бы сохранить полученный звук в AVAudioFile для дальнейшего использования.

Это моя текущая реализация, и файл действительно содержит данные. Это wav-файл, но он не является воспроизводимым аудиофайлом. Я думаю, что в моем форматировании может быть что-то не так, вот мой подход.

     private enum Setting {
        static let formatID = Int(kAudioFormatLinearPCM)
        static let sampleRate = 16000
        static let numberOfChannels = 1
        static let encoderQuality = AVAudioQuality.min.rawValue
    }

    private let settings: [String: Any] =
        [AVFormatIDKey: Setting.formatID,
         AVSampleRateKey: Setting.sampleRate,
         AVLinearPCMIsFloatKey: true,
         AVNumberOfChannelsKey: Setting.numberOfChannels,
         AVEncoderAudioQualityKey: Setting.encoderQuality]


    func record() {
        let mixer = AVAudioMixerNode()
        audioEngine.attach(mixer)
        let format = AVAudioFormat(settings: settings)
        audioEngine.connect(audioEngine.inputNode, to: mixer, format: audioEngine.inputNode.inputFormat(forBus: 0))
        audioEngine.connect(mixer, to: audioEngine.outputNode, format: format)
        
    guard let destinationURL = FileManager.default.whs_generateWAVFile() else { return }
        do {
            file = try AVAudioFile(forWriting: destinationURL, settings: mixer.outputFormat(forBus: 0).settings, commonFormat: .pcmFormatFloat32, interleaved: true)
            mixer.installTap(onBus: 0, bufferSize: 1024, format: mixer.outputFormat(forBus: 0)) { (buffer, time) in
                do { try self.file?.write(from: buffer); print("Wrote (buffer)") } catch { print("Error: (error)") }
            }
            audioEngine.prepare()
            do { try audioEngine.start() } catch { print("Big error:  (RecordingError.audioEngineStart.description)"); return }
        } catch {
            print("Big Error:  (RecordingError.audioEngineStart.description), (error)")
        }
    }
   
  

Ответ №1:

Это потому, что вы не закрыли AVAudioFile, в который вы записываете. Установите для файла значение nil при остановке движка, и wav-файл будет воспроизводиться.