On iPadOS13 all "AVAudioPlayerNodes" that are attached to an "AVAudioEngine" are over-released after a "Media Service Rest".
My application uses the "AVAudioEngine" similar to the "AVAudioEngine3DAudioExample".
When I reset the media service (settings>developer>reset media service) my application receives an "AVAudioSession.mediaServicesWereResetNotification". When my app receives this notification, the app reattaches the player nodes to a new AVAudioEngine.
Like this example from "AVAudioEngine3DAudioExample" ( ~ line 438).
// Example form AVAudioEngine3DAudioExample
- (void)createEngineAndAttachNodes {
_engine = [[AVAudioEngine alloc] init];
[_engine attachNode:_environment];
[_engine attachNode:_launchSoundPlayer];
for (int i = 0; i < _collisionPlayerArray.count; i++)
[_engine attachNode:[_collisionPlayerArray objectAtIndex:i]]; // <- Crash
}
// Example in Swift as I use it in my app
func createAVAudioEngineAndAttachNodes() {
// Create a new engine
self.avAudioEngine = AVAudioEngine()
self.avAudioEngine.attach(self.avAudioEnvironmentNode)
// Attach all nodes.
for player in self.allAudioPlayers {
self.avAudioEngine.attach(player)// <- Crash
}
}
Crash:
EXC_BAD_ACCESS (code=1, address=0x0)
#0 0x0000000187538240 in objc_retain ()
#1 0x00000001944b83a8 in -[AVAudioPlayerNode didAttachToEngine:] ()
#2 0x00000001944c4690 in AVAudioEngineImpl::AttachNode(AVAudioNode*, bool) ()
#3 0x00000001944c7dcc in -[AVAudioEngine attachNode:] ()
#4 ....
I'm using swift 5 and the code works perfectly on iOS12 and macOS. I assume the media reset somehow destroys the AVAudioPlayerNode because it crashes when the AVFoundation framework trys to retain the audio player.
Can someone confirm this issu or provide a workaround?