How to shut down the music in background mode on IOS program? - ios

I make a iOS program to use the AVAudioPlayer to play music on the background. But I don't know how to shut down the music after a certain time.
I try to use the UILocalNotification to stop music in the method:
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)notification
But the way only effectly after the user recieved the Notification and click to shut down!
How can I stop the music automatically after a certain time?

If you use AVPlayer instead of AVAudioPlayer you can achieve this using addBoundaryTimeObserverForTimes:queue:usingBlock:
I have tried this with AVQueuePlayer (which is a subclass of AVPlayer) and it worked.
Try something like this:
id observer = [avPlayer addBoundaryTimeObserverForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:CMTimeMake(60, 1)]] queue:NULL usingBlock:^{
[avPlayer pause];
}];
And somewhere later:
[avPlayer removeTimeObserver:observer];

I would love to be proved wrong, but I believe that what you're asking to do might be impossible. My impression is that if the user actually clicks the Home button to send your app into the background, it can't function as a "sleep timer", because you can't run a timer. Apple's own apps can do this sort of thing, but they have special privileges.
For example, look at this app:
https://itunes.apple.com/us/app/music-sleep-timer/id320583424?mt=8
Look at how he says, "Remember to keep this app in the foreground!" Clearly that's because once the app is background, the timer stops working.
You might be better off advising the user to resort to the countdown timer in Apple's Clock app. It can shut down your music and put the device to sleep.

Related

iOS AVPlayer v. MPMusicPlayerController

I am writing a music playing app which performs a task between each song. I need to do this even when the app is in the background, so I need to know when a song has completed. At the moment I am using AVPlayer which sends notifications even when the app is in the background, but is unable to play songs from the user's iCloud. MPMediaPlayerController can play iCloud songs but doesn't send notifications when the app is in the background (which is essential to my app).
So, does anyone know either
Any clever ways of having AVPlayer play iCloud songs, or
Having my app recognise when a song playing via MPMusicPlayerController has completed when the app is in the background?
Have you tried using NSNotification Center and one of these two observers?
MPMusicPlayerControllerPlaybackStateDidChangeNotification or MPMusicPlayerControllerNowPlayingItemDidChangeNotification.
Also, you need to use beginGeneratingPlaybackNotifications() on your instance of MPMusicPlayerController.applicationMusicPlayer() or MPMusicPlayerController.systemMusicPlayer()
To build on #Kim's answer. You can use the NSNotificationCenter and add ObserverEvents. I use the MPMusicPlayerController class for my application, and I've registered the application to use the NSNotificationCenter properties so I can call certain methods during differing events.
For instance, while using the SystemMusicPlayer property if you exit and terminate the application process, the music keeps playing. If the user wanted to stop the music when they exityou could call this:
-(void) registerMediaPlayerNotifications {
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self
selector:#selector(stopMusicWhenApplicationQuits)
name:UIApplicationWillTerminateNotification
object:[UIApplication sharedApplication]];
[musicPlayer beginGeneratingPlaybackNotifications];
}
Where you see the #selector that is the method that will be fired when the application receives the UIApplicationWillTerminateNotification event. Which in the musicPlayer you can say
[self.musicPlayer stop];
So for the question you have, you can still use the MediaPlayer framework, use the MPMusicPlayerController class and call various methods during different application runtime stages using the NSNotificationCenter properties.
Hope this helps, let me know if you have any further questions.

Resuming Spotify after pause on iOS

I have an app that I want to be able to pause and resume the current playing song. The only way I've found so far is this:
[[MPMusicPlayerController systemMusicPlayer] pause];
// some time passes
[[MPMusicPlayerController systemMusicPlayer] play];
The problem is that if it's a 3rd party app that is playing, like Spotify, it seems to lose focus to the iOS Music.app when I do this. So when I try to resume with [ play], the last played song in Music.app starts playing.
Is there a way to pause and resume Spotify (or whatever app was playing) without losing focus to the Music.app? Aka, the exact same behaviour as pressing play/pause in iOS Action Center
There's sadly no way to do this (with public API that is, there are private API's but if you want to go in the AppStore you can't use them).

iPhone background audio without remote

I've been searching how to start an audio file after a couple of seconds when the app enters background, and it's working, but there's a small issue I'd love to get rid of.
Without the following code, the AVAudioPlayer won't begin playing:
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
But with this code, notification center starts acting like a remote.
I've seen (alarm) apps play a sound after some time, without notification center acting like a remote.
Any suggestions?
You can find the example code here:
https://github.com/SabatinoMasala/iPhone-background-audio
If you are not playing audio when entering in background mode, your app will be suspended.
Maybe adding [[UIApplication sharedApplication] beginReceivingRemoteControlEvents] will prevent your app to be suspended but I am not sure.
Have to tried to create a backgroundTask and play this audio file after a delay?
Also if you want to stay playing in background you have to loop a sound containing silence.

Opening Siri stops AVAudioPlayer

I am currently using an AVAudioPlayer to play looped music in the background of my app. However, when siri is opened in my application it turns it off. I am farly experienced with objective c but I cant seem to get this to work. Is there any way I can tell when a user opens siri so that I can start the AVAudioPlayer again after it stops. Please help!
P.S I have attempted continuously playing the audio but then siri wont work.
You can use AVAudioPlayerDelegate's audioPlayerEndInterruption:withOptions:
- (void)audioPlayerEndInterruption:(AVAudioPlayer *)player withOptions:(NSUInteger)flags {
[player play];
}
For anyone else coming to this, the endInterruption delegate isn't getting called from me when my app gets interrupted by Siri. I had to make the app resume playing when it becomes active again (using a notification).

background options and air play

How can I get my video to play via air play when the device falls asleep? I'm finding some things to do like this but it sounds like most of these things will get me banned from the app store. I just want my app's video to play on airplay without the user have to make sure their device stays awake. What should I do?
If I understand correctly, you want to prevent the device from going to sleep so you can play your video without interruptions. You can have your app prevent the device from "going to sleep" like this:
[UIApplication sharedApplication].idleTimerDisabled = YES;
Just remember to set it back to NO when you are done playing your video like this:
[UIApplication sharedApplication].idleTimerDisabled = NO;
I don't know how you are playing your video, but try you can probably just call those functions before you play your video, or immediately after you are done.
You can prevent the device from sleeping like this:
UIApplication* app = [UIApplication sharedApplication];
[app setIdleTimerDisabled:true];
when you're done with the video, don't forget to let it sleep again.
[app setIdleTimerDisabled:false];

Resources