AVAudioPlayer Does Not Respect Mute - ios

There are other topics on this but I can't comment in them, and I've tried all the approaches listed.
My app has a song that plays when it opens, but hitting the mute on the iPad has no effect (it should mute the song).
Here's my code where I start the sound:
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[[NSBundle mainBundle] URLForResource:#"intro_theme" withExtension:#"wav"] error:NULL];`
[audioPlayer play];
And here's the various approaches I've tried:
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: nil];
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryAmbient error: nil];
UInt32 sessionCategory = kAudioSessionCategory_AmbientSound;
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory);
Other people seem to be able to get AVAudioPlayer to respect the mute option - any ideas?

Have you tried the category AVAudioSessionCategorySoloAmbient?
per Apple's docs:
When you use this category, audio from other apps is silenced. Your audio is silenced by screen locking and by the Silent switch (called the Ring/Silent switch on iPhone).

Here is a solution:
I delayed playing my audio using an NSTimer until 1 second after the call to setCategory. This is working on iPad 3 & iPad 1 (haven't tested on 2).

Related

Simulate phone call on hands-free to play audio files with AVAudioPlayer

Many older cars have no option to play music from external bluetooth devices (A2DP), they are only able to handle phone calls (hands free). But some navigation apps are able to play sounds simulating a phone call. This way, the radio/CD-player gets interrupted as long as the navigation app plays the sound.
Has anyone an idea how to do this with AVAudioPlayer? Or another method? I could not find any infos related.
That's what I have so far, but I guess I'm completely wrong..
NSUInteger optionsFlag = (AVAudioSessionCategoryOptionAllowBluetooth | AVAudioSessionCategoryOptionMixWithOthers | AVAudioSessionCategoryOptionDuckOthers);
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback withOptions:optionsFlag error: nil];
NSURL *soundFileURL = #"/path/to/soundfile.wav";
player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
[player play];

AVAudioPlayer cannot play on background when Youtube playing

I make an alarm feature for my app, at the time I setup for alarm fire I can play a music track with AVAudioPlayer, it worked well on background mode. But if at this time I opening Youtube app and playing a video then the AVAudioPlayer not work.
Please tell me why this happen and how to resolve this issue, how to play both at the same time
This is code I implement:
NSURL *soundURL = [[NSBundle mainBundle] URLForResource:#"remind2"
withExtension:#"mp3"];
avSound = [[AVAudioPlayer alloc]
initWithContentsOfURL:soundURL error:nil];
[avSound setDelegate:self];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[avSound prepareToPlay];
[avSound setNumberOfLoops:10];
[avSound setVolume:1.0];
[avSound play];
Thanks!
This is happened because of Youtube app also set property "UIBackgroundMode" property in plist. And even if you check any of other Music app like gaana, savan, etc. this will happened in all of the music app.
Replace this line
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
by this:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil];
and I resolved my problem
It takes me two days to put the right questions to this problem, I only find the solution when i ask Google why Youtube stop my audio stream and this result search help me
AVAudioPlayer turns off iPod - how to work around?

iOS: How to play buffering audio in bluetooth headset in my music app?

I am currently doing one music app. in that i need to play buffering
audio song in blue tooth headset. i searched for code past 1 day. but
i can't. please give solution how to add this in my music app.
One more thing i need to play that audio in bluetooth headset while iphone is in backeground mode and screen lock mode.
AVAudioSession* audioSession = [AVAudioSession sharedInstance];
//[audioSession setDelegate:self];
NSError *error;
[audioSession setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionAllowBluetooth error:&error];
[audioSession setActive: YES error: nil];
// check the audio route
UInt32 size = sizeof(CFStringRef);
CFStringRef route;
OSStatus result = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &size, &route);
NSLog(#"route = %#", route);
// if bluetooth headset connected, should be "HeadsetBT"
// if not connected, will be "ReceiverAndMicrophone"
// now, play a quick sound we put in the bundle (bomb.wav)
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
SystemSoundID soundFileObject;
soundFileURLRef = CFBundleCopyResourceURL (mainBundle,CFSTR ("sample"),CFSTR ("m4a"),NULL);
AudioServicesCreateSystemSoundID (soundFileURLRef,&soundFileObject);
AudioServicesPlaySystemSound (soundFileObject); // should play into headset
I have added this code in my music app. but this code is for Bundle audio file. but i need buffering audio. if it is not possible please tell is my code is correcte to play local audio file through blue tooth headset.?
From what i read in the documentation , setting the category for the audio session should be
AVAudioSessionCategoryPlayAndRecord
or
AVAudioSessionCategoryRecord
if setting the option to
AVAudioSessionCategoryOptionAllowBluetooth
so you should change that, another thing when i look at the enum: AVAudioSessionCategoryOptions the option to bluetooth is __TVOS_PROHIBITED but i don't know the alternative...

AVAudioSession with AVPlayer: The 'Play' Icon in the status menu not showing when the AVPlayer player is playing

I have an AVPlayer to stream an mp3 file from the web. I have activated an AVAudioSession so that the audio will play when the app is exited / screen turned off. The music plays perfectly, but the little 'Play' triangle icon that appears in the status menu at the top of the phone is not appearing when the music is playing (as is the usual case in iOS). Anything I'm doing wrong? Code below
// Set AudioSession
NSError *sessionError = nil;
[[AVAudioSession sharedInstance] setDelegate:self];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&sessionError];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
//Direct audio to speakers when there is no headphone
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory);
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);
For those who may come across this question, I figured it out. You have to make your player's controller the first responder - specifically for remote control events. Not only does this allow you to receive the remote control events (like the universal play/pause/forward/back controls), but it also puts the play icon in the status menu.
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];

How to use kAudioSessionProperty_OverrideCategoryMixWithOthers

I would like to make my virtual instrument app able to being used (via a MIDI keyboard) when the app is in the background. This works fine by setting UIBackgroundModes to "audio" and setting the AudioSessions's category to AVAudioSessionCategoryPlayback. Furthermore, to allow mixing with the Music player app, I set the property kAudioSessionProperty_OverrideCategoryMixWithOthers.
To save battery energy, it is recommended to let the user switch off the background operation if it is not needed. So there is a switch in my app to toggle between the category AVAudioSessionCategoryAmbient and the category AVAudioSessionCategoryPlayback (with kAudioSessionProperty_OverrideCategoryMixWithOthers). The code is like this (error handling omitted):
NSString *category = supportsBackgroundOperation ? AVAudioSessionCategoryPlayback : AVAudioSessionCategoryAmbient;
[session setCategory:category error:nil];
if (category == AVAudioSessionCategoryPlayback) {
UInt32 allowMixing = true;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(allowMixing), &allowMixing);
}
Now the problem: Suppose the Music application is playing in the background. The user is playing the virtual instrument in the foreground (via a MIDI keyboard) to accompany the Music player and decides to start yet another app, say a slide show to enjoy why playing the instrument. So he/she goes to the settings view of my app and activates background operation. Then the above code is executed. Boom, the Music application gets silent. As I understand it, the kAudioSessionProperty_OverrideCategoryMixWithOthers property can only be set after setting the category, but when I set the category to AVAudioSessionCategoryPlayback, the Music player is silenced by the system before I have a chance to set kAudioSessionProperty_OverrideCategoryMixWithOthers.
Is this was happens? Can there anything be done? I tried to deactivate/activate the session before/after changing the category, but that lead to other trouble.
Markus
Since iOS 6.0 you can use
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil];
Swift 5:
try? AVAudioSession.sharedInstance().setCategory(.playback, options: .mixWithOthers)
You can achieve this. The principle is to deactivate your audio session first, setup all the properties of your audio session, and then active audio session. In this way, the music playbacked in other app will not be silenced.
// Initialize audio session
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
// Active your audio session
[audioSession setActive: NO error: nil];
// Set audio session category
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
// Modifying Playback Mixing Behavior, allow playing music in other apps
OSStatus propertySetError = 0;
UInt32 allowMixing = true;
propertySetError = AudioSessionSetProperty (
kAudioSessionProperty_OverrideCategoryMixWithOthers,
sizeof (allowMixing),
&allowMixing);
// Active your audio session
[audioSession setActive: YES error: nil];
This solution works for me. But from your description, You mentioned that you did try activate/deactivate the session before/after changing the category but lead to other problems. Did you do the deactivate/activate in the exact same way as above? If so, provide more information about other troubles and maybe I can help.
I have to disagree with M0rph3v5.
The only valid value for the withOptions parameter is AVAudioSessionInterruptionOptionShouldResume

Resources