iOS: Keep playing music in background with Spotify SDK - ios

I'm using the Spotify iOS SDK and have a question about the background music.
When a user locks the phone or presses the Home button I want my app to continue to play the music. How is this possible?
I've tested
NSError *setCategoryErr = nil;
NSError *activationErr = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error:&setCategoryErr];
[[AVAudioSession sharedInstance] setActive:YES error:&activationErr];
Together with adding "Required background modes" to the apps plist.
Does this require that the AVAudioPlayer is used? Since I'm using the Spotify streamingPlayer its not possible.

Background playback should work just fine. You do need the audio item in your UIBackgroundModes Info.plist entry, though. Also, make sure you test on a device - I know remote control events don't work in the iOS Simulator, and that might be the case for background audio as well.
The iOS SDK will automatically set up the AVAudioSession for you, so you don't need to do that.
You might find this answer helpful, which is more in-depth: Background Audio with cocoalibspotify.

Related

iOS AVAudioSession ducking is slow and synchronous

In iOS, I'm trying to duck the Music app's music when playing some sound effects. In case you don't know, "ducking" simply means that the music volume gets a bit down before playing my sound, then the sound plays, and then the music volume gets back its initial volume.
For ducking, I'm setting AVAudioSession category to AVAudioSessionCategoryAmbient with option AVAudioSessionCategoryOptionDuckOthers, and then activating/deactivating the session (and playing the sound in-between, obviously). It works well, but the volume changes seem to be done in the same thread as the call, and the app hangs while the volume is being modified.
If you want to replicate the behavior, I think the fastest route is to start a new SpriteKit project, which will give you the sample, ship rotating project. Then put the following code in the touchesBegan:withEvent method:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient withOptions: AVAudioSessionCategoryOptionDuckOthers error: nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
[[AVAudioSession sharedInstance] setActive:NO error:nil];
Next run the app in an iOS device, put some music in the Music app and touch the screen to create ships and duck the music. You'll hear the ducking, but also see the ships freezing on the screen.
Is this normal? What would be the simplest way to avoid the app freezing while the ducking is made?
By the way, I'm using an iPhone 5S on iOS 8.1. Also, I'm using this in a Unity3D plugin. How can I duck the Music app from Unity itself?
You can try putting the AVAudioSession calls on a different thread. Then they won't be blocking the main (UI) thread. This is especially for setActive, which takes a noticeable amount of time to complete.
dispatch_queue_t myQueue = dispatch_queue_create("com.myname.myapp", nil);
dispatch_async(myQueue, ^{
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient withOptions: AVAudioSessionCategoryOptionDuckOthers error: nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
});
This question also seems relevant: iOS AudioSessionSetActive() blocking main thread?

MPMoviePlayer stops playing going in background

need to play audio in background with MpMoviePlayerController. I know that I have to use this code to achieve that:
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
[audioSession setActive:YES error:nil];
and set the "RequireBakgroundMode" in the pList.
This is working fine except for that when I put my app in background the sound stops and I have to open control center and press play to resume playback.
So my question is, how can I avoid the sound stopping when the app goes in background? Thanks
Set of Capabilities of you project.its working fine when apps enter in Background.
When you make enable mode then in plist file set background mode automatically.

MPMusicPlayerController Play music while app is in background

Hope this question doesn't get down voted - I haven't seen anything in the documentation.
I want to play music from the ipod library while the app is in the back ground.
I am creating the music player using the default mechanism.
-(void)viewWillAppear:(BOOL)animated
{
MPMusicPlayerController *myPlayer =
[MPMusicPlayerController applicationMusicPlayer];
// assign a playback queue containing all media items on the device
[myPlayer setQueueWithQuery: [MPMediaQuery songsQuery]];
// start playing from the beginning of the queue
[myPlayer play];
}
As soon as the app enters the background the music stops playing. I would like it to continue playing though.
I do not want to use the iPodMusicPlayer option
How can I do this?
You should set background audio mode in the project settings (Project settings > Capabilities > Background modes > Audio and AirPlay) like it's shown on the screenshot below:
Also you should set Audio Session Category in the appDelegate (in the didFinishLaunching method). Example is shown below:
NSError *setCategoryErr = nil;
NSError *activationErr = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error:&setCategoryErr];
[[AVAudioSession sharedInstance] setActive:YES error:&activationErr];
I have same issue. I searched even after added flag in plist. It will not work because :
The applicationMusicPlayer does not support background music. Use
MPMusicPlayerController's systemMusicPlayer instead. It shares the
state with the built-in System player and music will continue to play
when your app enters the background.
Other Solution is :
You can use AVAudioPlayer to play either streamed or local(bundle) audio. It even allows you to play multiple audio file at the same time having an AVAudioPlayer instance for each.
Note : iPodMusicPlayer is deprecated. so Instead of this use systemMusicPlayer.

iOS MPMoviePlayerViewController stop playing when screen locks

I implement MPMoviePlayerViewController to play video and I enable airPlay and works great but the problem is when the screen on the ipad locks. My question is how can make sure the MPMoviePlayerViewController still in airPlay even when the screen locks. Any of you knows how can I make this work?
Where as Apple thinks that When user can't see the video what is the benefit to runs consistently? So there is no need to play Video when you can't see it. Apple pauses it when app goes to background or screen locks. If you still want to play it you can add notification to start and stop when you go to background and come to foreground.
Hope this helps.
In your Info.plist file, add the key "Required background modes" with the value "App plays audio or streams audio/video using AirPlay".
Also, when you receive the notification MPMoviePlayerIsAirPlayVideoActiveDidChangeNotification, add these lines:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
And add this line to your dealloc method:
[[AVAudioSession sharedInstance] setActive:NO error:nil];

Background Audio in iOS

I'm trying to build an iOS App (iOS > 5.0). It should play music files when a timer, set by the user, ends. Here is my setup what if done so far:
I use avplayer
I've set Background Modes in my plist to "App plays Audio"
in my appDelegate I have:
NSError *sessionError = nil;
[[AVAudioSession sharedInstance] setDelegate:self];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&sessionError];
before a song is going to be played a set:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&sessionError];
[[AVAudioSession sharedInstance] setActive:YES error:&sessionError];
i notify my application on "playerItemDidPlayToEnd", stop the player and tell other apps like the music.app to become active again
_avPlayer = nil;
NSError *sessionError = nil;
[[AVAudioSession sharedInstance] setActive:NO withFlags:AVAudioSessionSetActiveFlags_NotifyOthersOnDeactivation error:&sessionError];
This works fine. You can have your music app playing in background. My App starts to play a song the music app fades away. My song is played and if its finished the music app continues to play. But only as long as my app isn't in background.
In background I get the error:
Error Domain=NSOSStatusErrorDomain Code=560161140 "The operation couldn\u2019t be completed. (OSStatus error 560161140.)"
Is it possible that both combinations of, playing in background (on custom events) and switching between f.e. music.app and my app in background isn't possible?
Here a the code of my player model: http://pastie.org/4830995
I think your problem might be with background handling. You need to override this function on app delegate.
- (void)applicationDidEnterBackground:(UIApplication *)application
{
__block UIBackgroundTaskIdentifier task = 0;
task=[application beginBackgroundTaskWithExpirationHandler:^{
NSLog(#"Expiration handler called %f",[application backgroundTimeRemaining]);
[application endBackgroundTask:task];
task=UIBackgroundTaskInvalid;
}];
}
your application will get killed after 6 minutes unless sound is played. If your user set timer for more then 6 minutes, what you could do is to play short quite sound every 5.5 minutes to keep you app alive and start new background task. Also you have to consider that lot of thing will not get executed in background. I did some stuff somewhat similar to what you are doing. What I did was created custom subclass of NSObject witch handled music playback and application expiration stuff. And made it a strong property on my delegate as lot of functions and notifications will not run on you VC in the background.
Although if you just want to play a sound this might not be the best approach. Maybe just sending local notification would do.
Hope this helped.
Did you register your app to keep running in the background as an audio app? To do so, add the UIBackgroundModes key to your Info.plist file and set its value to audio.

Resources