Swift开发:如何等待提示音播放完毕再启动录音?
解决录音提示音被录入的问题
问题出在AudioServicesPlaySystemSound是异步执行的,调用后代码会立刻启动录音,此时提示音还在播放,自然会被录进文件里。要解决这个问题,你需要监听系统音效的播放完成事件,等提示音播放结束后再启动录音。
具体实现方案:
- 注册系统音效播放完成的回调,在回调里执行录音启动逻辑
- 记得在回调触发后移除监听,避免内存泄漏和重复触发
修改后的代码示例:
@State var recorder: AVAudioRecorder! @State var isRecording = false // 定义开始录音的音效ID let recordStartSoundID: SystemSoundID = 1113 func startRecording() { do { let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] let fileName = url.appendingPathComponent("myRcd.m4a") let settings = [ AVFormatIDKey: Int(kAudioFormatMPEG4AAC), AVSampleRateKey: 44100, AVNumberOfChannelsKey: 1, AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue ] self.recorder = try AVAudioRecorder(url: fileName, settings: settings) self.recorder.prepareToRecord() // 提前准备录音资源,减少启动延迟 // 注册音效播放完成的回调 AudioServicesAddSystemSoundCompletion( recordStartSoundID, nil, nil, { (soundID, clientData) in guard let recorder = Unmanaged<AVAudioRecorder>.fromOpaque(clientData!).takeUnretainedValue() else { return } DispatchQueue.main.async { recorder.record() self.isRecording.toggle() // 移除回调,避免重复触发 AudioServicesRemoveSystemSoundCompletion(soundID) } }, Unmanaged.passUnretained(self.recorder).toOpaque() ) // 播放开始录音提示音 AudioServicesPlaySystemSound(recordStartSoundID) } catch { print("录音初始化失败: \(error.localizedDescription)") } }
额外注意:
- 调用
prepareToRecord()可以提前完成录音的初始化工作,避免在回调中启动录音时出现卡顿 - 如果停止录音的提示音也有类似问题,同样可以套用这个逻辑,等提示音播放完毕再停止录音
内容的提问来源于stack exchange,提问作者buleva
相关产品推荐
相关产品推荐

