I am getting audio from mic. with using AvAudioEngine but when coming call and makes interruption, I want to stop and then restart getting audio process but When I try handleInterruption(I shared below) method I am getting this error. how can I stop and restart AvAudioEngine after interruption
AURemoteIO.cpp:1702 AUIOClient_StartIO failed (561145187) AVAEInternal.h:109 [AVAudioEngineGraph.mm:1545:Start: (err = PerformCommand(*ioNode, kAUStartIO, NULL, 0)): error 561145187 Can't start the engine: Error Domain=com.apple.coreaudio.avfaudio Code=561145187 "(null)" UserInfo={failed call=err = PerformCommand(*ioNode, kAUStartIO, NULL, 0)}
@objc func handleInterruption(notification: Notification) {
guard let userInfo = notification.userInfo,
let typeValue = userInfo[AVAudioSessionInterruptionTypeKey] as? UInt,
let type = AVAudioSession.InterruptionType(rawValue: typeValue) else {
return
}
// Switch over the interruption type.
switch type {
case .began:
print("interrupt begin")
socket.close()
socket=nil
self.socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: DispatchQueue.main)
audioEngine.stop()
print("Audio player stopped")
case .ended:
print("interrupt end")
self.audioEngine = AVAudioEngine()
self.audioPlayer = AVAudioPlayerNode()
self.mixer = AVAudioMixerNode()
do {
try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .voiceChat, options: [.allowBluetooth, .allowBluetoothA2DP])
print("Audio session category set to playback")
} catch {
print("Setting category to AVAudioSessionCategoryPlayback failed: \(error)")
}
self.mixer = AVAudioMixerNode()
self.mixer.volume = 0
self.audioEngine.attach(audioPlayer)
self.audioEngine.attach(mixer)
try! self.audioEngine.inputNode.setVoiceProcessingEnabled(true)
try! AVAudioSession.sharedInstance().setActive(true)
DispatchQueue.global(qos: .background).async { [weak self] in
guard let self = self else { return }
do {
self.socket.setIPv4Enabled(true)
self.socket.setIPv6Enabled(false)
try self.socket.connect(toHost:"239.10.10.100" ?? "", onPort: 4545 ?? 0)
try self.socket.beginReceiving()
print("Socket started")
} catch {
print("Socket Started Error: \(error)")
}
}
audioEngine.inputNode.installTap(onBus: 0, bufferSize: 1024, format: audioEngine.inputNode.inputFormat(forBus: 0)) {
(buffer: AVAudioPCMBuffer!, time: AVAudioTime!) -> Void in
do {
let inputBlock: AVAudioConverterInputBlock = { _, outStatus in
outStatus.pointee = AVAudioConverterInputStatus.haveData
return buffer
}
let frameCapacity =
AVAudioFrameCount(self.outputFormat.sampleRate) * buffer.frameLength
/ AVAudioFrameCount(buffer.format.sampleRate)
let outputBuffer = AVAudioPCMBuffer(
pcmFormat: self.outputFormat,
frameCapacity: frameCapacity
)!
var error: NSError?
self.converter.convert(to: outputBuffer, error: &error, withInputFrom: inputBlock)
//let data = Data(bytes: (outputBuffer.int16ChannelData![0]), count: Int(outputBuffer.frameLength))
let data = Data(buffer: UnsafeBufferPointer(start: outputBuffer.int16ChannelData![0], count: Int(outputBuffer.frameLength)))
print(data)
DispatchQueue.global(qos: .background).async { [weak self] in
guard let self = self else { return }
do {
self.socket.send(data, withTimeout: 0, tag: 0)
} catch {
print("Socket send Error: \(error)")
}
}
} catch {
print(error)
}
}
audioEngine.prepare()
do {
try audioEngine.start()
print("Audio player started")
} catch {
print("Can't start the engine: \(error)")
}
default:
print("Default print")
break
}
}
The error you're seeing (
561145187) isAVAudioSessionErrorCodeCannotStartRecording.These days I think you're only allowed to restart audio IO if your
AVAudioSession.InterruptionOptionscontain.shouldResume. This doesn't always happen!If this is a problem, you could try making it less likely that you be interrupted by adding
.mixWithOthersto youAVAudioSessioncategory options. You will need.playAndRecordand not.recordin this case.