Describe the bug
Problem Description: When I use broadcast to record the screen and system audio (while also capturing mic audio), if a call comes in, regardless of whether I answer the phone or not, the recording of system audio will be interrupted. Afterward, without restarting the app, it will always be unable to record system audio. I investigated the cause, and the issue lies in the method public func capture(appAudio inputBuffer: AVAudioPCMBuffer) in MixerEngineObserver.swift. In this method, the condition engine.isRunning is not met, resulting in the system audio not being mixed and sent. I tried to fix it:
- I added
pause and start methods to MixerEngineObserver for pausing and starting the audio engine. The specific code is as follows:
extension MixerEngineObserver {
public func pause() {
let appNode = _state.read {
$0.appNode
}
guard let engine = appNode.engine else {
log("Engine is not running engine == nil", .warning)
return
}
try? engine.pause()
appNode.pause()
}
public func start() {
let appNode = _state.read {
$0.appNode
}
guard let engine = appNode.engine else {
log("Engine is not running engine == nil", .warning)
return
}
do {
try engine.start()
} catch {
log("Engine start failed \(error)", .error)
}
appNode.play()
}
}
- When constructing
AudioManager, I added a listener for AVAudioSession.interruptionNotification. When receiving the event, I use the methods added to MixerEngineObserver. The specific code is as follows:
init() {
#if os(iOS) || os(visionOS) || os(tvOS)
let engineObservers: [any AudioEngineObserver] = [audioSession, mixer]
#else
let engineObservers: [any AudioEngineObserver] = [mixer]
#endif
_state = StateSync(State(engineObservers: engineObservers))
_admDelegateAdapter.audioManager = self
RTC.audioDeviceModule.observer = _admDelegateAdapter
NotificationCenter.default.addObserver(
self,
selector: #selector(handleAudioSessionInterruption),
name: AVAudioSession.interruptionNotification,
object: AVAudioSession.sharedInstance()
)
}
@objc
private func handleAudioSessionInterruption(_ notification: Notification) {
guard
let info = notification.userInfo,
let typeValue = info[AVAudioSessionInterruptionTypeKey] as? UInt,
let type = AVAudioSession.InterruptionType(rawValue: typeValue)
else { return }
switch type {
case .began:
log("AudioSession interruption began", .info)
try? AVAudioSession.sharedInstance().setActive(false)
mixer.pause()
case .ended:
let optionsValue =
info[AVAudioSessionInterruptionOptionKey] as? UInt ?? 0
let options = AVAudioSession.InterruptionOptions(rawValue: optionsValue)
if options.contains(.shouldResume) {
log("AudioSession interruption ended, resuming", .info)
try? AVAudioSession.sharedInstance().setActive(true)
mixer.start()
}
@unknown default:
break
}
}
Fix Results:
- Now, when a call comes in, the recording of system audio will be interrupted, but if the user brings my app to the foreground, the recording of system audio can be restarted.
Issues with the Fix:
- The problem is that the user must bring my app to the foreground to resume; if not, it still won't record system audio. The issue is that
AVAudioEngine cannot be restarted in the background.
I hope to automatically resume recording system audio even without the user bringing the app to the foreground. Can this be done without using AVAudioEngine for mixing? Thanks!
SDK Version
2.10.1
iOS/macOS Version
iOS17, 18, 26
Xcode Version
Xcode 16+, Xcode 26
Describe the bug
Problem Description: When I use broadcast to record the screen and system audio (while also capturing mic audio), if a call comes in, regardless of whether I answer the phone or not, the recording of system audio will be interrupted. Afterward, without restarting the app, it will always be unable to record system audio. I investigated the cause, and the issue lies in the method
public func capture(appAudio inputBuffer: AVAudioPCMBuffer)in MixerEngineObserver.swift. In this method, the conditionengine.isRunningis not met, resulting in the system audio not being mixed and sent. I tried to fix it:pauseandstartmethods toMixerEngineObserverfor pausing and starting the audio engine. The specific code is as follows:AudioManager, I added a listener forAVAudioSession.interruptionNotification. When receiving the event, I use the methods added toMixerEngineObserver. The specific code is as follows:Fix Results:
Issues with the Fix:
AVAudioEnginecannot be restarted in the background.I hope to automatically resume recording system audio even without the user bringing the app to the foreground. Can this be done without using
AVAudioEnginefor mixing? Thanks!SDK Version
2.10.1
iOS/macOS Version
iOS17, 18, 26
Xcode Version
Xcode 16+, Xcode 26