Background and foreground apps using audio - ios

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.

Related

Can AVAudioSession be activated in Background state without MixWithOthers?

So my app is running in the background because of CoreLocation that has requested AlwaysAuthorization. This prevents app to reach suspended state. It stays in background state and is receiving location events. After some location events I would like to activate AVAudioSession and play some sounds. How to activate session properly (in this background app) when I'm using other app in foreground right now and this app is playing audio track for example. Suppose I'm watching some video in Youtube app and my background app needs to play audio right now. I've problems in activating audio session in this case.
I can't use AudioToolbox playing engine in this case because those sounds needs to be played even when Ring/Silent switch is on.
I know I need to use AVAudioSessionCategoryPlayback category. I also don't want other apps to be played in the same time so I'm not using MixWithOthers or DuckOthers category options.
I have enabled UIBackgroundModes for audio playback in background.
How to activate such session when app is in background and other app currently is playing audio without any mixing options enabled. How to interrupt audio session in current foreground app so my background app can activate it for playback time. After playing is over my plan is to deactivate audio session in background and notify other apps that they can resume theirs playback.
Add these below 3 lines in the didFinishLaunchingWithOptions method of AppDelegate.m class and test the app again. Let me know if there is any problem regarding the same.
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
[UIApplication sharedApplication].idleTimerDisabled = YES;

Audio triggered by background location

Target OS: iOS 6+
Devices: Phones only
I'm creating an fairly simple locative media app. The one technical difficulty I'm having is whether or not I can do what I want with background audio.
I receive GPS location updates successfully in the background but I would like to use these to trigger audio on region entry. The app does not play audio constantly in foreground, only on entry to these fences.
Does the 'playing silence' trick still work to keep the Audio Session and is this an app where Apple would tolerate its use? If so could anyone provide recently functional code for it?
If you set up your application to also enable background audio, in application:didFinishLaunching: like so:
[[AVAudioSession sharedInstance] setDelegate: self];
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
and add audio as a background mode in the app's plist file, your app will keep on running in the background and play sounds when it wishes (e.g. when a location change has happened). However, I think you have to close the application while playing sound.
However, there might be an issue with this, because background audio is meant for apps that actually keep running a track/stream in the background. I could see how Apple might reject your app for using their API in an unintended way. So this is the problem with the playing silence trick.
Also, another problem could be that if the user goes out of your app, then starts playing their music through Music or any other music app (Spotify, a radio app etc.) that has access to background audio, your application's audio permissions will be disabled (your app won't be able to play sound anymore through the audio framework, because another app has taken control of the background audio).
An option I would recommend: throw a local notification with your own sound when the user changes location:
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
localNotif.soundName = #"your-sound-file-name";

Play video in UIWebview background on Airplay

I have an app that plays several webvideos like Youtube and Vimeo in a UIWebView. When the video plays it is possible to send it to an Apple TV over AirPlay.
Currently, during playback over AirPlay the video stops when I pause the app and move it to the background.
My desired result is that the video will keep playing on the Apple TV.
After some research I found out that I have to set the Required background modes in the Info.plist to App plays audio. Unfortunately this did not work.
So what does need to be set to keep the video playing over AirPlay when the app is moved to the background.
i've tested this on iOS6 with UIWebView loading video webpage, and it does the job. the audio session needed to be set as AVAudioSessionCategoryPlayback in order to be played in background.
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];

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

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.

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