I have a video capturing app and I want to be able to play background music while recording audio+video.
I can accomplish this if I set the AVAudioSession category to PlayAndRecord in didFinishLaunchingWithOptions. However, this causes a glitch in the audio whenever the view with the camera enters or exits the foreground, and its apparently impossible to get rid of: https://forums.developer.apple.com/message/74778#74778
I can live with the glitch if it just happens when I start/stop recording video, but that means I need to change the AVAudioSession category from Ambient to PlayAndRecord when a button is pressed, and this also seems to not be possible.
How do I change the AVAudioSession category?
I tried this:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord
withOptions:AVAudioSessionCategoryOptionMixWithOthers
error:nil];
But the background music stops when the recording starts.
Following this post: AVCaptureSession and background audio iOS 7
I tried deactivating the session then setting the category:
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:&error];
[session setCategory:AVAudioSessionCategoryPlayAndRecord
withOptions:AVAudioSessionCategoryOptionMixWithOthers | AVAudioSessionCategoryOptionDefaultToSpeaker
error:nil];
[session setActive:YES error:&error];
I also tried listening for the AVAudioSessionRouteChangeNotification and setting the category in that handler after deactivating the session. But the background music always turns off when the app starts recording.
Why can't I change the AVAudioSession category?
Please try this category
AVAudioSessionCategoryMultiRoute
or check both categories
AVAudioSessionCategoryPlayAndRecord | AVAudioSessionCategoryRecord
Related
I need to allow my app to record audio without stopping background music player.
I'm using AVAudioRecorder.
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
However, anytime [audioplayer record] is called, the background music will stop playing.
What can I do so that background music doesn't stop playing?
Thanks.
You need to add the MixWithOthers Category Option as well:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord
withOptions:AVAudioSessionCategoryOptionMixWithOthers
error:nil];
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?
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.
I am trying to play video in background everything works just fine and the video play and get pause normally in background.But the only problem is whenever I go back from the from my
videoviewcontroller(the view on which is played to menu), the video still remains in the background and you can see it as Musicplayer position. How can this be removed once I get out of videoviewcontroller
I have tried
NSError *error;
[[AVAudioSession sharedInstance] setActive:NO error:&error];
NSLog(#"ERROR: %#", error);
output
ERROR: (null)
this code removes the video from the background
[[AVAudioSession sharedInstance] setCategory:nil error:nil];
but if now if want to play the video again it will not play in background mode
From Apple's:AVAudioSession class documentation
It says
Deactivating your session will fail if any associated audio objects (such as queues, converters, players or recorders) are currently running.
So you need to stop any/all of this audio objects before calling the setActive:No
I had had similar issues while trying to perform this before stopping my audio queue.
In mi case I was using an external audio library (Dirac) and I just needed to call an AudioQueueStop method from this library before.
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