Music is getting stopped when application come from background to foreground - ios

I am developing the chat application , If someone sends any message to me & my app is in background then i receive that message and i play the tone whenever message received,while tone is playing in mean while application is opened then music is getting stopped . How to make it continue when app comes to foreground also. (Tone must be complete as per duration available init). How to solve this issue. Waiting for the answer.

You have to work on remote control received events with notification..
- (void)remoteControlReceivedWithEvent:(UIEvent *)theEvent {
if (theEvent.type == UIEventTypeRemoteControl) {
switch(theEvent.subtype) {
case UIEventSubtypeRemoteControlPlay:
[[NSNotificationCenter defaultCenter] postNotificationName:#"TogglePlayPause" object:nil];
break;
case UIEventSubtypeRemoteControlPause:
[[NSNotificationCenter defaultCenter] postNotificationName:#"TogglePlayPause" object:nil];
break;
case UIEventSubtypeRemoteControlStop:
break;
case UIEventSubtypeRemoteControlTogglePlayPause:
[[NSNotificationCenter defaultCenter] postNotificationName:#"TogglePlayPause" object:nil];
break;
default:
return;
}
}
}
you can view complete answer here

You will have to use AVAudioSession. You can have the music temporarily pause or lower in volume while alert plays, then it'll resume full force!
First to initialize audio:
AVAudioSession* audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil]
[audioSession setActive:NO error:nil];
Playing the sound (AVAudioPlayer's play/prepareToPlay will activate the audio session for you):
AVAudioPlayer* audioPlayer = [[[AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:nil];
[audioPlayer play];
Stopping the alert sound:
[audioPlayer stop];
[[AVAudioSession sharedInstance] setActive:NO withFlags:AVAudioSessionSetActiveFlags_NotifyOthersOnDeactivation error:nil];
The flag kAudioSessionSetActiveFlag_NotifyOthersOnDeactivation tells the system to notify background audio to resume playing after the sound is played.

Related

my app media play in background mode didn't play if once I open apple music app

I have problem with media play in background mode.
In my app I have to play media play in background mode when server send any notification through socket connection.
In my case media player working fine when app in background mode.
Problem is when app in background mode if I play music app and stop the music player and send notification to my app .Than my app didn't play media player.
I added in plist this one "App plays audio or streams audio/video using AirPlay"
I am using "AVPlayer"
Please help me.
Thanks.
If you look into the AVPlayer documentation it says that it can only play one asset at a time. I think Apple Music uses if not the same API something that is related to this.
AVPlayer is intended for playing a single media asset at a time. The
player instance can be reused to play additional media assets using
its replaceCurrentItem(with:) method, but it manages the playback of
only a single media asset at a time
1). Put this code in you AppDelegate.m (didFinishLaunchingWithOptions) methods :
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
2). After that set Background Modes active for Audio, Airplay and Picture in Picture
Might be, its due to Interruption with current AVplayer running item.
Also, take care you implemented it(Below code)before loading any item to AVPlayer. AND enabled Capabilities to Play audio in background.
NSError *myErr;
[self becomeFirstResponder];
[[UIApplication sharedApplication]beginReceivingRemoteControlEvents];
AVAudioSession *aSession = [AVAudioSession sharedInstance];
[aSession setCategory:AVAudioSessionCategoryPlayback error:&myErr];
[aSession setMode:AVAudioSessionModeDefault error:&myErr];
[aSession setActive: YES error: &myErr];
Implement and Add Interruption handler, so you can re-play your stopped audio after another audio/interruption stopped. and below listener of it will call.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(handleAudioSessionInterruption:)
name:AVAudioSessionInterruptionNotification
object:aSession];
And manage AVplayer play/pause again in it:
- (void)handleAudioSessionInterruption:(NSNotification*)notification {
NSNumber *interruptionType = [[notification userInfo] objectForKey:AVAudioSessionInterruptionTypeKey];
NSNumber *interruptionOption = [[notification userInfo] objectForKey:AVAudioSessionInterruptionOptionKey];
switch (interruptionType.unsignedIntegerValue) {
case AVAudioSessionInterruptionTypeBegan:{
// • Audio has stopped, already inactive
// • Change state of UI, etc., to reflect non-playing state
IsInteruptionOccured=YES;
} break;
case AVAudioSessionInterruptionTypeEnded:{
// • Make session active
// • Update user interface
// • AVAudioSessionInterruptionOptionShouldResume option
IsInteruptionOccured=NO;
[[AVAudioSession sharedInstance] setActive: YES error: nil];
if (interruptionOption.unsignedIntegerValue == AVAudioSessionInterruptionOptionShouldResume) {
// Here you should continue playback.
// Resume after exteranl interruption.
[_audioPlayer play];
BOOL isPlayingWithOthers = [[AVAudioSession sharedInstance] isOtherAudioPlaying];
// test it with...
NSLog(#"other audio is playing %d",isPlayingWithOthers);
}
} break;
default:
break;
}
}

How to stop Avaudiosession from deactivating?

I want to play a song through speaker while being able to receive a video call using Quickblox.
My audio rates are getting messed up.
And also a bigger a problem is when the call ends quickblox framework sets audio session to deactivated state. i.e
[Avaudiosession sharedInstance]setActive:NO....
How do I stop this from happening?
Or is there a way the above mentioned scenario can be handled.??
I have read through google for a month now and still didn't find any suitable answers or any guidelines.
Can anyone help me with this problem/??
First, to allow AVAudioSession to work with other AVAudioSessions, you'll need to set up the option AVAudioSessionCategoryOptionMixWithOthers when initializing it:
NSError *sessionError = NULL;
BOOL success = [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback
withOptions:AVAudioSessionCategoryOptionMixWithOthers
error:&sessionError];
if(!success) {
NSLog(#"Error setting category Audio Session: %#", [sessionError localizedDescription]);
}
To handle interruptions (a call, alarm, etc..), you should set up an observer for interruptions to the NSNotificationCenter where you'll be able to handle the activation/deactivation of the AVAudioSession if necessary:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(handleAudioSessionInterruption:)
name:AVAudioSessionInterruptionNotification
object:[AVAudioSession sharedInstance]];
The NSNotification will carry the Type of Interruption and Key:
- (void)handleAudioSessionInterruption:(NSNotification*)notification {
NSNumber *interruptionType = [[notification userInfo] objectForKey:AVAudioSessionInterruptionTypeKey];
NSNumber *interruptionOption = [[notification userInfo] objectForKey:AVAudioSessionInterruptionOptionKey];
switch (interruptionType.unsignedIntegerValue) {
case AVAudioSessionInterruptionTypeBegan:{
// • Audio has stopped, already inactive
// • Change state of UI, etc., to reflect non-playing state
NSLog(#"AVAudioSessionInterruptionTypeBegan");
} break;
case AVAudioSessionInterruptionTypeEnded:{
// • Make session active
// • Update user interface
// • AVAudioSessionInterruptionOptionShouldResume option
NSLog(#"AVAudioSessionInterruptionTypeEnded");
if (interruptionOption.unsignedIntegerValue == AVAudioSessionInterruptionOptionShouldResume) {
// Here you should continue playback.
}
} break;
default:
break;
}
}

Stream radio from url with AVPlayer -> iPhone player controls not working

I use AVPlayer to stream a live sound from a url.
It works perfectly except when my app is in background and I want to play or pause the iPhone player in the swipe-up menu (I dont know its exact name). The volume controls work, but not the play/pause controls.
I have been looking through SO and the internet for hours and cant figure it out.
Any help?
Here is the code (dont hesitate if you need any more code):
// Set AudioSession
NSError *sessionError = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&sessionError];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
// Init player
self.playerItem = [AVPlayerItem playerItemWithURL:url];
self.audioPlayer = [AVPlayer playerWithPlayerItem:self.playerItem];
[self.audioPlayer play];
You need to implement the remote controls in your app yourself. This is not handled by AVPlayer.
Want you need to read is Remote Control Events.
You need make some class the firs responder, like your root view controller. Make sure it is receiving al the event by calling [self becomeFirstResponder].
Then just implement the event handler for remote control events:
- (void)remoteControlReceivedWithEvent:(UIEvent *)receivedEvent {
if (receivedEvent.type == UIEventTypeRemoteControl) {
switch (receivedEvent.subtype) {
case UIEventSubtypeRemoteControlTogglePlayPause:
[self playOrStop: nil];
break;
case UIEventSubtypeRemoteControlPreviousTrack:
[self previousTrack: nil];
break;
case UIEventSubtypeRemoteControlNextTrack:
[self nextTrack: nil];
break;
default:
break;
}
}

AVAudioSession can't play sound after app re-becomes active

So I have a music app that uses an AVAudioSession to allow it to play when it is in the background. I use this call:
[audioSession setActive:YES
withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation
error:nil];
My problem now is if I go to another app and it steals the audio session (thus now stopping music playback from my app and playing something else), and I come back to my app, no matter what I do to reset my audio session or my audio units, my app's sound is gone.
Does anyone know what to do?
So after registering for the AVAudioSession notifications:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(handleAudioSessionInterruption:)
name:AVAudioSessionInterruptionNotification
object:aSession];
You need to resume/restart you need to restart your player in the handler interruption type is AVAudioSessionInterruptionTypeEnded:
- (void)handleAudioSessionInterruption:(NSNotification*)notification {
NSNumber *interruptionType = [[notification userInfo] objectForKey:AVAudioSessionInterruptionTypeKey];
NSNumber *interruptionOption = [[notification userInfo] objectForKey:AVAudioSessionInterruptionOptionKey];
switch (interruptionType.unsignedIntegerValue) {
case AVAudioSessionInterruptionTypeBegan:{
// • Audio has stopped, already inactive
// • Change state of UI, etc., to reflect non-playing state
} break;
case AVAudioSessionInterruptionTypeEnded:{
// • Make session active
// • Update user interface
// • AVAudioSessionInterruptionOptionShouldResume option
if (interruptionOption.unsignedIntegerValue == AVAudioSessionInterruptionOptionShouldResume) {
// Here you should continue playback.
[player play];
}
} break;
default:
break;
}
}
You can see a complete explanation here: AVplayer resuming after incoming call

How does app like heard works?

I want to make app which continuously records voice in background. App like heard does exactly that.
But I am stuck on interruptions. The app fail to resume recording when it faces interruptions.
I have used this for notification :
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(handleAudioSessionInterruption:)
name:AVAudioSessionInterruptionNotification
object:nil];
and to resume recording I have:
- (void)handleAudioSessionInterruption:(NSNotification*)notification {
NSNumber *interruptionType = [[notification userInfo] objectForKey:AVAudioSessionInterruptionTypeKey];
NSNumber *interruptionOption = [[notification userInfo] objectForKey:AVAudioSessionInterruptionOptionKey];
switch (interruptionType.unsignedIntegerValue) {
case AVAudioSessionInterruptionTypeBegan:{
// • Audio has stopped, already inactive
// • Change state of UI, etc., to reflect non-playing state
NSLog(#"Audio has stopped, already inactive");
NSLog(#"is recording: %#",recorder.isRecording?#"yes":#"no");
[self.recorder pause];
NSLog(#"is recording after pause: %#",recorder.isRecording?#"yes":#"no");
//[recorder pause];
} break;
case AVAudioSessionInterruptionTypeEnded:{
// • Make session active
// • Update user interface
// • AVAudioSessionInterruptionOptionShouldResume option
if (interruptionOption.unsignedIntegerValue == AVAudioSessionInterruptionOptionShouldResume) {
// Here you should continue playback.
//NSLog(#"completed");
NSLog(#"start recording again %d");
//NSLog(#"completed: %d",[recorder record]);
// Set the audio file
[self.recorder record];
NSLog(#"is recording after again : %#",recorder.isRecording?#"yes":#"no");
//[player play];
}
} break;
default:
break;
}
}
Add in the plist the UIBackgroundModes an 'audio' as Item 0. Hope it will help - at least it works for me when playing audio.

Resources