MPMoviePlayerController and AVAudioPlayer audio mixing glitch
Asked Answered
A

1

22

I'm developing an interactive storybook type application for the iPhone and I've recently encountered a frustrating bug concerning audio mixing on the device.

Firstly, I setup an audio session. I set the category to AVAudioSessionCategoryAmbient and then init and play my AVAudioPlayer instance. Now, in the background whilst the audio is playing I'm pre-loading a video to play using an MPMoviePlayerController followed by a call to prepareToPlay. The reason I pre-load the video this way is because I need it to play instantly later on cue with fairly strict timing.

In this configuration, the audio/movie works fine and they mix and do not interrupt each other. However, this particular audio session category does not permit audio to continue playing while the device is locked, a feature I really need. As a result I'm forced to consider a different category: AVAudioSessionCategoryPlayback.

By default this category does not permit mixing with other audio, according to the Apple docs. To enable mixing with other audio I am overriding the relevant category:

OSStatus propertySetError = 0;
UInt32 setProperty = 1;
propertySetError = AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(setProperty), &setProperty);
assert(propertySetError == 0);

Unfortunately, this solves my playing whilst locked issue but introduces another issue: the AVAudioPlayer audio is interrupted briefly as the video loads with a minor stutter. The stutter is small, perhaps less than a second but is enough to disrupt the user experience. I've read this related post which enabled me to pre-load the video with the AVAudioSessionCategoryAmbient, but unfortunately the same approach doesn't seem to work with the new category.

The audio session category is applied successfully, according to the return code. Does anyone know why enabling audio mixing with this category is not the same as the mixing facility provided by ambient category?

Alegre answered 31/1, 2011 at 18:2 Comment(4)
Thanks! I hope I have the formatting correct!Alegre
Have you tried using AVPlayer to playback the video rather than mixing between the two frameworks?Compost
By the way, to delimit mid-sentence phrases as a class name or similar, try surrounding the name with backticks (`Like so`) :)Pronty
+1 @Compost for the AVPlayer for video. Also, try dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ /* do AVAudioPlayer stuff */ }); to run your audio operations on a high-priority background thread for a lower chance of interruption due to video loading on the main thread.Pronty
S
1

The best way I've found working a similar problem is to use the newer AVPlayer (+1 @adam) and set your app to enable background audio and receive remote control notifications. I was tipped off to this by @MarquelV following How can you play music from the iPod app while still receiving remote control events in your app?

If you can get backgrounding working properly, that should enable you to continue playing while the device is locked. Oh, and don't forget to add keys to info.plist, its easy to do and then have no idea why it isn't working.

Strychnine answered 16/8, 2011 at 13:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.