Pausing song when a video begins playing (and vice-versa) - ios

I have an app that uses AVPlayer to play songs and a UIWebView to play YouTube videos. When I build it against iOS 5, the audio and video refuse to play together, which I like. Pressing play on one will automatically pause the other, with a nice half-second fade-out.
Now that I'm building against iOS 6, this behavior is gone -- the songs and videos play over each other. How can I get back the iOS 5 behavior?

add the shared categories in your App delegate:
NSError *setCategoryErr = nil;
NSError *activationErr = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: &setCategoryErr];
[[AVAudioSession sharedInstance] setActive:YES error:&activationErr];
this will limit to only one active audio session

Related

How to stop other app's music when ever my app plays music

I'm working on a music app in objective c. I just want that whenever my app plays music other apps like Spotify's music should be paused.
You can achieve that using the following:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback
withOptions:AVAudioSessionCategoryOptionDuckOthers | AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers
error:nil];
Hope that helps!

How can you configure AVAudioSession to duck music and pause spoken audio?

I'm working on a navigation app that uses AVSpeechSynthesizer to call out directions. If I'm playing a podcast I would like to be able to pause the audio while a direction is spoken and resume it afterwards. This is successfully achieved using:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback
withOptions:AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers
error:nil];
However, if I play music using the above code the instruction gets mixed with the music without the volume of the music being reduced - making it difficult to hear the instruction. So I tried:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback
withOptions:AVAudioSessionCategoryOptionDuckOthers
error:nil];
Now the background music reduces in volume, which is what I want, but when I play spoken audio (i.e. a podcast) it is no longer paused and instead gets mixed with the instruction - albeit at a reduced volume.
What I really want is something like: AVAudioSessionCategoryOptionInterruptSpokenAudioAndDuckWithOthers. However, that doesn't exist. I know that this combination is possible, because other apps (like Waze) have this behaviour.
I know that you can detect when audio is playing using:
BOOL isOtherAudioPlaying = [[AVAudioSession sharedInstance] isOtherAudioPlaying];
But, I couldn't find a way of determining if that Audio was spoken or not. If I could I could set things up according to what is playing at any given time. Can anyone help with this, preferably in Objective C?
This is how it's done:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback
withOptions:AVAudioSessionCategoryOptionDuckOthers | AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers
error:nil];
Works a charm!

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?

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.

How can I play a video without causing music on iTunes/other audio to pause

I'm using AVPlayer to play a video (open to alternative players). My videos don't have sound. When the video starts, if the IOS device is playing music/audio of some sort, the music/audio pauses even though the video has no sound.
Is there any way to continue playing music while playing a silent movie?
Try preparing the audio session before starting playback:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
[[AVAudioSession sharedInstance] setActive:NO error:nil];
//... create & configure AVPlayer and start playback

Resources