AVAudioPlayer, using AmbientSound session, is not playing when app is in background - ios

If this is in the apple doc then I've not been able to find it - hoping someone can help:
My app plays occasional short audio clips - I want the audio to mix in with audio playing from other apps in the background like the iPod app - but I also want it to carry on playing these audio clips when the app is running in background.
I have set "App plays audio" in the Required Background Modes settings in info.plist (the app is also using location services too so that is also set in there)
My app sets up an audio session on applicationDidFinishLaunching:
AudioSessionInitialize (NULL,NULL,NULL,NULL);
UInt32 sessionCategory = kAudioSessionCategory_AmbientSound;
AudioSessionSetProperty (kAudioSessionProperty_AudioCategory,sizeof (sessionCategory),&sessionCategory);
AudioSessionSetActive(true);
In my viewWillAppear: method in the view that is active I have:
[super viewWillAppear:animated];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
and the corresponding event handler and endReceivingRemoteControlEvents code in viewWillDisappear: as discussed in iOS 4: Remote controls for background audio
Finally I have an AVAudioPlayer, set up in the normal way, that plays a sound on certain events
bool successful = [avAudioPlayer play];
if(!successful)
NSLog(#"did not play");
When the app is in foreground the app works fine and plays the audio - but when the app goes into background and the app attempts to play a sound the return value from the [avAudioPlayer play] is NO and the sound does not play - when switched back to foreground the audio starts working again.
If when I set up the session I instead use
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
Then the audio plays in foreground and background perfectly. But MediaPlayback is not the really the right mode for this app since I am only occasionally playing audio clips - AmbientSound is really the mode I should be using.
What am I missing? Is it just not possible to use kAudioSessionCategory_AmbientSound to play Audio in the background? If so I've not found anything in the documentation about that.

Had to submit a tech support request for this in the end.
According to Apple background playback is not supported by the AmbientSound category - you have to use MediaPlayback.
They claim this is in the documentation - I've looked again and I could not find it.
Ok so getting background sounds to mix into MediaPlayback is easy enough using kAudioSessionProperty_OverrideCategoryMixWithOthers - but I am now going to have to jump through some other hoops to replicate the other AmbientSound functionality (obeying the mute switch and not playing when locked). I really don't understand why AmbientSound is not supported playing in background - but there we go.

Related

How can I avoid interrupting audio that is already playing when my app launches?

I have an app that needs to use AVAudioSessionCategoryPlayback in order to play sound while the device is locked or my app is in the background. (It's an alarm feature.) So I also need to set the "audio" key in my UIBackgroundModes list.
I have put the following code in my application:didFinishLaunchingWithOptions: method:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback
withOptions:AVAudioSessionCategoryOptionMixWithOthers
error:nil];
However, I don't want to interrupt any music that is already playing on the device. When my app is launched, it causes Spotify (for example) to stop playing music. I can switch to Spotify and press play, and when I switch back to my app, it continues playing.
But this is very annoying to the user - alarms are not the only thing my app does, and there are many reasons for them to launch it that don't involve setting alarms. I don't think the user would ever want my app to stop any other audio playing on the device.
Ideally I'd never interrupt already-playing audio. I could also live with stopping audio when an alarm is set (at which point I have to activate my audio session to ensure that I'm able to play it) but it seems like there is no way for me to avoid the audio stop at app launch.
Is there some way to start my app with the audio session disabled, or to start it with this option already applied?
It turns out that I was calling .prepareForPlayback() on an AVAudioPlayer in an init() method which was getting called long before my didFinishLaunchingWithOptions: fired.

Pause all audio from the background - iOS Tweak

I am making a jailbroken iOS tweak and have a question. How can I stop all device audio while running from the background. Example: The user is playing Spotify and then clicks the power button on the device(turning off the screen and putting it to sleep) meanwhile Spotify is still playing music. At this point how can I stop stop all audio on the device(whether it's Spotify, default music app, Pandora, or whatever)? I have look into AVAudioSession and AVAudioPlayer but have not found a consistent reliable method to do this. I am testing this on a jailbroken iPhone5 running iOS7.0.4.
I am open to using AVAudioSession or AVAudioPlayer if it works consistently. I am also open to using something from a private framework to accomplish this. Thanks!
Thanks!
I figured it out, use this:
SBMediaController *mainMediaController = [%c(SBMediaController) sharedInstance];
[mainMediaController pause];

Background and foreground apps using audio

I did some preliminary test and have a good idea the answer is no. But just need to confirm: Can a background and foreground app share audio playback device? (The background app will be mine. The foreground app will be from third party)
That is possible and here is how:
Make sure that app continues playing audio when left in background by doing this:
a) add the following to your Info plist file:
"Required background modes"
"Item 0" -> "App plays audio"
b) Call setCategory:error: for AVAudioSession of your app:
NSError *setCategoryError = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError];
Allow your audio to be mixed with audio from other apps by calling AudioSessionSetProperty():
OSStatus propertySetError = 0;
UInt32 allowMixing = true;
propertySetError = AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers,
sizeof (allowMixing),
&allowMixing
);
You will need to link against AVFoundation and AudioToolbox frameworks for this code.
Technically this is possible. While a background app is playing music, the foreground app is still allowed to play sound effects (like the "Music" app is playing music while you hear the sound effects of the game you're playing foreground). So you could declare the music a foreground app plays as a sound effect while another app plays music in background.
But if you can't control the foreground app, to get them play their music as a sound effect, than there is no way.
I also doubt that an app that declared continuos music a sound effect will make it through Apple review process.

IOS 5 No audio when playing a video with Silent mode on with a buzztouch app

I have done several apps with buzztouch for Iphone and Ipads, here is a free one as an example :
http://itunes.apple.com/us/app/lr-basics-free-edition/id497563707?mt=8
I do not know code very much, I have very little basics that is why I designed my app using Buzztouch, which by the way is amazing !
The only one problem that I have is that the default behavior when you play a video (which was most of my apps are doing, playing tutorials) and if the silent mode is on either on Ipad or Iphone, there is no audio, even thought the volume slider is active, given the impressions to users that there is a bug, and I got some bad reviews due to that, I have also people writing me about it. I Then tell them all they have to do is to turn off the silent mode and they the audio is back, works everytime, but in the meantime I get complaits !
So here is my questions, is there a simple way I can located in the Buzztouch generated code a property that can easely be changed so that when a video is played, audio stays, despiste the silent mode being active.
I actually checked 4 or 5 other Iphones similar applications including the default youtube apple app, the default is that the audio plays even if the silent mode is turn on, giving my customer the impression that my app is bugged.
I'm not a programmer so please but as simple as possible in your answer.
Tku so much for the help.
Serge
What you are describing is the default behavior in iOS - when the ring/silent switch is in silent mode all audio from your app will be suppressed.
I don't know about implementing this from BuzzTouch, but here is a native solution I used to get around this for one of my apps that plays video:
MPMoviePlayerViewController *mpvc = [[MPMoviePlayerViewController alloc] initWithContentURL:myVidURL];
... set up player ...
// prevent mute switch from switching off audio from movie player
NSError *_error = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: &_error];
[self presentMoviePlayerViewControllerAnimated:mpvc];
You will also need to include the AVFoundation framework for this to work.
Here's the link where I first found this tip:
http://www.24100.net/2011/05/ignore-ringtone-mute-switch-during-mpmovieplayer-video-playback-ios/
Right from documentation - iOS has 6 audio session categories out of that 3 affects the behavior of Slient switch:
AVAudioSessionCategoryAmbient or the equivalent kAudioSessionCategory_AmbientSound— Using this category, your audio is silenced by the Ring/Silent switch and when the screen locks. Used when we want our app audio with built-in app audio
AVAudioSessionCategorySoloAmbient or the equivalent kAudioSessionCategory_SoloAmbientSound—Use this category for an application whose audio you want silenced when the user switches the Ring/Silent switch to the “silent” position and when the screen locks. This is the default category
AVAudioSessionCategoryPlayback or the equivalent kAudioSessionCategory_MediaPlayback—Use this category for an application whose audio playback is of primary importance. Your audio plays even with the screen locked and with the Ring/Silent switch set to silent.
Hint: Upload the audio file to your buzztouch account files. This is the only way Buzztouch will recognize the audio. next, add the audio file to your xcode bttouch sound folder and add all references. You should be fine!

Continue playing audio from html5 player when in iOS background mode

We built our music-oriented app in html5 and javascript with Sencha touch. For distribution we wrapped it in xcode with UIwebView. Everything runs fine except one thing that does not work: audio playing in multitask mode.
I know the general idea: add the UIBackgroundModes in info.plist.
Done. Now we can play the audio even in background mode.
Until we reach the end of the song. To start the next song we have to bring the app to foreground again or we can hit the play or 'next song' button on the iPhone audio controller.
After some research I found a promising workaround at: " Entering background on iOS4 to play audio " where the workaround is to edit AVAudioSessionCategoryPlayback and work with the UIBackgroundTaskIdentifier.
The problem for me is (just like in any other fix I found so far) that those solutions always assume that the audio is played either with AVaudioPlayer or MPMusicPlayerController. But in my case I user neither, our audio is played by our html5 player wrapped in UIwebView.
Anyone has any advice on how to continue playing the audio in iOS multitask mode when the audio player is a html5/javascript player?
My app plays audio via an <audio> tag in html hosted in UIWebView, and it supports background playing.
As you suggest, you need to have the 'App plays audio' background mode defined in your plist.
Try adding this to your applicationDidFinishLaunching: handler:
NSError *setCategoryError = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: &setCategoryError];
Thanks, guys, but I ended up simply keeping the app busy in a loop when in background mode. This was enough to bridge the time when connecting to the next song on the playlist.
The code I used is similar to this one:
iPhone - Backgrounding to poll for events
You could try this, adding a function on the onend event.

Resources