AudioKit首次录制正常,二次录制失败问题求助
AudioKit二次录制失败问题解决
问题描述
首次使用AudioKit框架时,首次录制功能运行正常。调用stopAKRecordingAndSave方法停止录制并关闭AudioEngine后,再次调用prepareToAKrecord尝试录制(已执行recorder.reset()操作)却无法成功,且二次录制时出现大量警告。疑问:是否遗漏总线清理的特殊方法?是否应保持引擎运行仅重置录制器?
相关代码
准备录制方法
func prepareToAKrecord() { // Setup microphone and reverb mic = engine.input reverb = Reverb(mic) reverb.loadFactoryPreset(.mediumRoom) //large hall etc engine.output = reverb do { // Check if the recorder is already recording if recorder?.isRecording == true { print("Recorder is already recording. Attempting to stop before reinitializing.") recorder?.stop() } // Reset the recorder if it exists if let existingRecorder = recorder { try existingRecorder.reset() print("Recorder reset successfully.") } recorder = try NodeRecorder(node: reverb, shouldCleanupRecordings: true) try self.engine.start() try self.recorder!.record() } catch { print("Failed to create recorder: \(error)") } }
停止录制方法
func stopAKRecordingAndSave() { self.isRecording = false //recorder!.stop() recorder.stop() engine.stop() if let recordedAudioFile = recorder!.audioFile { self.voiceURL = recordedAudioFile.url print("Recording saved to: \(self.voiceURL!)") //dec-4 self.mergeVoiceSong() // Merge this voice reverb and backing track //self.merging = false } else { print("Failed to get the recorded audio file") } UserDefaults.standard.set(false,forKey: "newSearch") }
问题原因与解决方案
核心问题
- 频繁启停AudioEngine:引擎启停属于重操作,频繁执行会导致音频会话状态冲突,且旧节点资源未被正确释放。
- 重复创建音频节点:每次调用
prepareToAKrecord都重新创建mic和reverb,旧节点未被清理,造成总线占用冲突。
优化方案
1. 保持AudioEngine持续运行
将引擎和音频节点的初始化逻辑移至全局初始化(如viewDidLoad),仅启动一次,避免频繁启停。
2. 复用音频节点,优化录制器逻辑
无需每次录制都重建节点,停止录制后仅重置录制器即可二次录制。
修改后的代码示例
全局初始化(以ViewController为例)
var engine = AudioEngine() var mic: AudioEngine.InputNode! var reverb: Reverb! var recorder: NodeRecorder? override func viewDidLoad() { super.viewDidLoad() // 仅初始化一次音频节点与引擎 mic = engine.input reverb = Reverb(mic) reverb.loadFactoryPreset(.mediumRoom) engine.output = reverb do { try engine.start() } catch { print("引擎启动失败:\(error)") } }
准备录制方法
func prepareToAKrecord() { do { // 若正在录制则先停止 if recorder?.isRecording == true { recorder?.stop() } // 重置已有录制器或创建新录制器 if let existingRecorder = recorder { try existingRecorder.reset() } else { recorder = try NodeRecorder(node: reverb, shouldCleanupRecordings: true) } try recorder!.record() self.isRecording = true } catch { print("录制准备失败:\(error)") } }
停止录制方法
func stopAKRecordingAndSave() { self.isRecording = false recorder?.stop() if let recordedAudioFile = recorder?.audioFile { self.voiceURL = recordedAudioFile.url print("录制文件已保存至:\(self.voiceURL!)") self.mergeVoiceSong() } else { print("无法获取录制文件") } UserDefaults.standard.set(false, forKey: "newSearch") }
额外注意事项
- 确保音频权限已正确申请,二次录制前可检查权限状态
- 若需在特定场景停止引擎,需彻底释放所有节点引用,下次启动时重新完整初始化
- 可通过控制台警告定位具体资源冲突问题,针对性调整代码
内容的提问来源于stack exchange,提问作者Nat Serrano
相关产品推荐
相关产品推荐

