Resume Background Audio After Playing Sound With AVAudioPlayer - ios

I am looking for a way to resume audio played by another application after my application plays its own sound with AVAudioPlayer. Right now, if I am listening to music and launch my application, it pauses the music, plays my sound, but doesn't resume the background music.
Here is what i'm doing to generate the sound playback:
myChime = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"chime" ofType:#"mp3"]] error:nil];
myChime.delegate = self;
[myChime play];
// Here I am looking to resume the audio that the system was playing before my application played its sound. I have seen many applications do this such as, GPS apps that speak a voice direction and then resume the music.

You need to properly implement the AVAudioSession delegate methods. If you set the audio session to inactive, then the system will know you are done playing your sound and will resume any other audio sessions. Refer to the Audio Session Programming Guide, especially the setActive:error: method.

Related

Multiple AVPlayers ducking?

I have a relatively simple setup involving 1 AVPlayer looping some ambient audio in the background and a second player playing a shorter sound at certain points.
What I've observed is that when the short sound is played, I hear the ambient clip cut out for about a second while there is a staticy pop. It then proceeds to continue playing while the short sound is played at the same time. This only happens on device - it's not noticeable on the sim, which seems to point to a potential performance issue.
I can't quite figure out why the first AVPlayer has this blip. Here is the code for the ambient player:
NSString *path = [[NSBundle mainBundle] pathForResource:kAmbientTrack ofType:#"mp3"];
_ambientPlayer = [AVPlayer playerWithURL:[NSURL fileURLWithPath:path]];
[self.ambientPlayer play];
It's slightly more complex, as I also listen for a notification when it ends and the restart it, but this issue happens even during the initial play before any looping occurs.
So while that is going in the background, I play another clip like so:
self.announcementPlayer = [[AVPlayer alloc] initWithURL:[myObject audioPathUrl]];
[self.announcementPlayer play];
So nothing too unique there - just two AVPlayers playing.
The only other piece of interest is how I set up the audio session when the app launches.
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil];
I'm doing this to allow the user to play music from other apps in the background.
I think my code is pretty straight forward, and really have no idea why I would be getting this blip.
I fixed this somewhat by changing the audio players to be AVAudioPlayers. That resolved the popping in most cases. However, I still get the ducking. Specifically, if I play an AVAudioPlayer and, while it's still playing, I start to load an AVPlayer, it cuts off the AVAudioPlayer for about a second. Here's what I'm talking about:
[myAVAudioPlayer play];
AVPlayer *player = [AVPlayer playerWithURL:[self.currentExercise videoPathUrl]];
The addition of that second line causes the first second or so of myAVAudioPlayer to be silent.

Play music in background and only stop in certain instances

I have an app that shows videos in a timeline. The videos autoplay and by default they should be silent. If the user is playing music in the background, music should not stop at this time. It is only when tapping the video that it should actually pause the background music and let the video play. And once the video is done playing, the user's previous audio should continue where it left off.
I've tried using
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
but this lets the music mix with the audio even if the video is in full screen mode. Of course, I could ensure that when the play button is tapped, the music pauses, but that might not be the cleanest solution.
Any better ideas?

AVPlayer removes background music

I've been using giffycat to decode, store, and play gifs in my app. I am making it so that it can easily load a gif in a UICollectionView's cell, so I have decided for each gif model to have its own AVPlayer. I have noticed that simply by creating an AVPlayer, shown bellow, audio from other apps is killed! Annoying for both the user and the creater!
// Create an AVURLAsset with an NSURL containing the path to the video
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:[NSURL URLWithString:_mp4] options:nil];
// Create an AVPlayerItem using the asset
AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset];
_player = [AVPlayer playerWithPlayerItem:item]; //if this line is commented out, I hear audio, else audio from Spotify is quickly killed...
Since these videos are just gifs, I am wondering if there is some way to unassign the audio session. I do not know much about this. ples help!
Turns out the answer is pretty easy, after a little googling and documentation reading...
The solution is
// audio session
let audioSession = AVAudioSession.sharedInstance()
try! audioSession.setCategory(AVAudioSessionCategoryAmbient,
withOptions: AVAudioSessionCategoryOptions.MixWithOthers)
oops, just realized I am posting my question in objC and answer in Swift. Well tough, because that's life sometimes.
AudioSession is a singleton for your entire app to rule how your application mingles with the other sounds of the system and other apps! The default audio session is
playback is enabled, recording is disabled
when user moves silent switch to "silent" your audio is silenced
when user presses sleep/wake button to lock screen or auto-lock period expires, your audio is silenced
when your audio starts, other audio on device (music) is silenced.
CategoryAmbient tells it not to do 4
Nice documentation!
https://developer.apple.com/library/ios/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/ConfiguringanAudioSession/ConfiguringanAudioSession.html#//apple_ref/doc/uid/TP40007875-CH2-SW1
Set the audioMix property of the AVPlayerItem to nil before creating an AVPlayer from it to remove the audio track from the asset.

Playing a silent movie with AVFoundation and keeping iPod music playing

I have an app that plays silent Movies using AVFoundation. Is there a way to allow the music to play and your iPod (if you're playing music) to continue playing? If I play the movie will my iPod is on, the iPod pauses so the movie can play, and vice versa - if I try to replay the music while the movie is playing, the movie pauses. Basically, I want them to play continue playing seamlessly....
Let me know if you need applicable code to answer.
In my experience, for standard AVAudioPlayer based sound in an app, managing the AVAudioSession is required to allow background music:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil];
But I can't tell you if that's the same as attempting to play encoded/compressed Video and encoded/compressed audio at the same time.

MPMoviePlayerController is not responding to device volume controls

I'm working on a game that during the title sequence plays a video in the background using MPMoviePlayerController. I overlay my game controls over this (just a few textured UIButtons).
The video itself has no audio, but I'm playing sounds when I press buttons via OpenAL.
The Audio Session is set to "Ambient" and whenever the MPMoviePlayerController is not around it responds correctly to device's mute button and volume. But as soon as the video starts playing it blares out the sounds with no regard to the mute or volume settings.
Can anyone help me? Is the MPMoviePlayerController interfering with the AudioSession state?
Is there a way to stop this from happening. My movie has no sound in it so it shouldn't need to do that.
The MPMoviePlayerController uses the AVAudioPlayer shared instance. So you can literally set the volume of the MPMoviePlayerController and it will turn down your background music. However, a better way is to tell MPMoviePlayerController to not use the shared instance.
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"intro" ofType:#"m4v"]];
self.player = [[MPMoviePlayerController alloc] initWithContentURL:url];
self.player.movieSourceType = MPMovieSourceTypeFile;
**[self.player setUseApplicationAudioSession:FALSE];**

Resources