8

I want to play audio file in the foreground, background and it should work with mute switch i.e. if mute switch is on, then it should not play, if mute switch is off should play audio.

**I'm developing an SIP call application. App should play sound/ringtone when user receives a call. It should play if app is in background/foreground, it should mute/unmute if hardware mute switch is ON/OFF.

For this I used AVPlyaer with below code.

AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback error:&error];
[session setActive:YES error:nil];

NSURL * audioFileUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test1" ofType:@"mp3"]];
AVPlayer *player = [[AVPlayer alloc] initWithURL: audioFileUrl];
[player play];

And also I added "App plays audio or streams audio/video using AirPlay" to background modes in info.plist

This is playing in both modes but not mute when hardware mute switch is ON. If I use AVAudioSessionCategoryAmbient not playing on the background mode. I used AVAudioPlayer but not able to find mute when hardware switch is ON

mfaani
  • 33,269
  • 19
  • 164
  • 293
Ganee....
  • 302
  • 2
  • 13

3 Answers3

3

Your Audio Session Category might be set incorrectly. Since you want to respect the mute switch, you should use SoloAmbient

AVAudioSessionCategorySoloAmbient

The category for default category, used unless you set a category with the setCategory:error: or setCategory:withOptions:error: method.

Your audio is silenced by screen locking and by the Silent switch (called the Ring/Silent switch on iPhone).

By default, using this category implies that your app’s audio is nonmixable—activating your session will interrupt any other audio sessions which are also nonmixable. To allow mixing, use the AVAudioSessionCategoryAmbient category instead.

Available in iOS 3.0 and later.

You appear to have used this category:

AVAudioSessionCategoryPlayback

The category for playing recorded music or other sounds that are central to the successful use of your app.

When using this category, your app audio continues with the Silent switch set to silent or when the screen locks. (The switch is called the Ring/Silent switch on iPhone.) To continue playing audio when your app transitions to the background (for example, when the screen locks), add the audio value to the UIBackgroundModes key in your information property list file.

By default, using this category implies that your app’s audio is nonmixable—activating your session will interrupt any other audio sessions which are also nonmixable. To allow mixing for this category, use the AVAudioSessionCategoryOptionMixWithOthers option.

Available in iOS 3.0 and later.

Source: https://developer.apple.com/library/prerelease/ios/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/index.html#//apple_ref/doc/constant_group/Audio_Session_Categories

Community
  • 1
  • 1
dss539
  • 6,804
  • 2
  • 34
  • 64
  • "AVAudioSessionCategoryAmbient" this is not playing in the background, "AVAudioSessionCategoryPlayback" this is not working with mute switch. Could you tell me the one work for both cases. Or else any other way to achieve it. – Ganee.... Aug 03 '15 at 07:04
  • @Ganee.... ok sorry I misunderstood. You want to play audio while the screen is off, but not while muted. Is this correct? Well then I have hit the same roadblock as you. Apple doesn't appear to offer an audio category for that. Sorry I was no help. :( – dss539 Aug 03 '15 at 13:11
  • But, how Skype is achieving this feature :(, any suggestions ? – Ganee.... Aug 04 '15 at 05:50
  • @Ganee.... sorry, I'm not an iOS dev. I don't even own an iOS device. I hope someone is able to help you. – dss539 Aug 05 '15 at 13:16
  • 1
    This answer solved my issue. I was receiving negative reviews in the app store because users had their phones on silent and thought the app was broken. I thought I had to have my audio session set to AVAudioSessionCategorySoloAmbient so you could play its audio over other apps / iTunes. However, using AVAudioSessionCategoryPlayback and setting its option to AVAudioSessionCategoryOptionMixWithOthers now allows my app to play sounds while in silent mode AND not interrupt other audio sources. Thank you! – vikzilla Feb 13 '16 at 19:13
2

Am happy to say, I found how skype is achieving this feature.

In foreground we can use AVAudioSession with any one category to play ringtone.

AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory: AVAudioSessionCategorySoloAmbient error:&error];
[session setActive:YES error:nil];

NSURL * audioFileUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test1" ofType:@"mp3"]];
AVPlayer *player = [[AVPlayer alloc] initWithURL: audioFileUrl];
[player play];

In background we have to use local notification with custom sound. This will work with hardware mute switch. But here sound file length should not exceed 30 seconds.

    UILocalNotification* notification = [[UILocalNotification alloc] init];
    [notification @"Title"];
    [notification setAlertBody:@"Body"];
    [notification setAlertAction:noteAction];
    [notification setSoundName:@"ringtone.mp3"];
    [[UIApplication sharedApplication] presentLocalNotificationNow:notification];

Hope this will be useful :).

Ganee....
  • 302
  • 2
  • 13
  • 1
    Can you provide more context to this code? I am unsure where you are implementing it / how it provides you with information regarding the silent switch. – vikzilla Feb 13 '16 at 19:05
  • It won't provide any information, notification sound will work according to silent switch, AVAudioSession will not work according to silent switch. – Ganee.... Feb 16 '16 at 12:19
  • @Ganee...., but how u handling, if suppose VoIP call came in background state and user clicked on it, after foreground came, how u managing to playing ringtone? – Anilkumar iOS - ReactNative Jun 17 '16 at 10:38
  • In background mode, when you click on notification, notification sound will be stop and app will open. After app opens (means in foreground mode) if call is still in ringing mode you can play audio using AVPlayer. – Ganee.... Aug 15 '16 at 15:51
  • @Ganee.... This looks like the right solution, thanks a lot! I still can't understand why Apple doesn't come with the right category that will obey the silent switch in both foreground and in background. – Guven Nov 21 '16 at 16:48
0

Here's a library used to detect mute switch state: http://sharkfood.com/content/Developers/content/Sound%20Switch/. It is based on Apple's Public APIs. It just plays system sound and measures amount of time used to complete playing. It was used in Instagram iOS app.

Nikita Zernov
  • 5,465
  • 6
  • 39
  • 70
  • This worked nicely for ios9, not using background usage – Miro Feb 01 '16 at 20:20
  • @Miro Can't get this to work for me. Any chance you can share your code? – vikzilla Feb 13 '16 at 18:55
  • their site gave me the code, but after you copy their .h/.m file into your project, it's pretty much: _detector = [SharkfoodMuteSwitchDetector shared]; _detector.silentNotify = ^(BOOL silent){ /* do something here */ } – Miro Feb 13 '16 at 20:16