从 AVAudioNodeTap 向 AVAudioFile 写入缓冲区(从 AVAudioEngine 保存录音)

Posted

技术标签:

【中文标题】从 AVAudioNodeTap 向 AVAudioFile 写入缓冲区(从 AVAudioEngine 保存录音)【英文标题】:Writing Buffer from AVAudioNodeTap to AVAudioFile (Save audio recording from AVAudioEngine) 【发布时间】:2020-09-24 22:40:31 【问题描述】:

我正在使用 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。停止引擎时将file设置为nil,wav文件将可以播放。

【讨论】:

以上是关于从 AVAudioNodeTap 向 AVAudioFile 写入缓冲区(从 AVAudioEngine 保存录音)的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS 中调整音频平衡

获取设备声音输出的当前音量 - iOS

无法在 iOS 中开始接收远程控制事件

iOS 无法在扬声器上播放并将音频会话设置为录制

有没有办法从另一个进程向线程发送信号?

如何从 UserDefaults 向数组添加值?