App ported to iOS 7 now requests microphone access - ios

We've almost finished porting our app to iOS7, but we've ran into an issue that AVPlayer defaults playback on the iPhone to the receiver (quiet speaker) instead of regular loud speaker. A solution for that appears to be using
AVAudioSession* session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback ...];
this, however, on iOS7 pops up a dialog requesting microphone permission. Why? How can I avoid this, as the app doesn't record anything? We're using AVPlayer for playback and also have background audio permission.

Have you tried to override output rote of Audio session? I've had similar problem on iOS 6 when sound was played on loudspeaker on iPod but on phone speaker on iPhone.
UInt32 audioRoute = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(UInt32), &audioRouteOverride);

Related

AVAudioSession: Record audio in app while simultaneously allowing Music app to play over bluetooth

I've been having trouble getting an app to record audio while simultaneously letting the iPhone music app play over bluetooth speakers.
For example if I do this:
[session setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionMixWithOthers | AVAudioSessionCategoryOptionDefaultToSpeaker error:&error];
session setActive:YES error:&error];
Then Music app will start playing music through the iPhone built in speaker instead of over bluetooth. In other words there appears to be no way to record audio in an app and still allow Music to play over bluetooth.
If I remove AVAudioSessionCategoryOptionDefaultToSpeaker , then the audio route will switch to the receiver. Which is worse than having it come through the iPhone speaker. Then I can set [session overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&error]; to force output back to the speaker, but this does not solve the bluetooth issue. Output will now be on the speaker just as with AVAudioSessionCategoryOptionDefaultToSpeaker.
How can I record audio and not interfere with playback over bluetooth from other apps (especially the Music app)?
You think you have to add AVAudioSessionCategoryOptionAllowBluetooth to your AVSession setCategory: to allow the bluetooth use.
Beside that, the microphone selected for recording will be the one set in the AVSession's [[currentRoute inputs] firstObject]. You should probably check it/change it accordingly if your bluetooth device have a microphone?

Keeping the video player silent after the recording is completed

How to keep the video player silent after the video recorder has been initialized and the silent switched is turned on?
In the application I am working on I have a video player (will call it player) and a video recorder (will call it recorder). If the phone is in silent mode (the switch on the side of the device is turned on to disable the sound) the player is kept silent when entering the application which is an expected and desired result. But after the recorder has begun running the session this behavior is lost and the video will play out loud although the silent mode is enabled.
I know specifically where this happens is when startRunning is called on an AVCaptureSession.
I also know the reason is somewhere in [AVAudioSession sharedInstance] category or mode property which seem to be changed right after the session begins running.
So what I do at the moment is call
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategorySoloAmbient error:&error];
[[AVAudioSession sharedInstance] setMode:AVAudioSessionModeDefault error:&error];
after the recording is completed to reset the session. The issue is this works in most but not all cases, sometimes reports error, sometimes works with a delay, sometimes doesn't work at all.
The possible solutions I am looking for are (any would do):
Somehow prevent the recorder to enable sound playing
Have a clear way of resetting the category and mode after the recording has completed (no errors or misbehaving)
Have a clean solution to find the state of the silence button (seems the old functions are deprecated and I found nothing but hacks)
Any other ideas welcome
An important information is that I have both the player and a recorder initialized all the time for a quick usage. Also I can control the player to be mute.
What I use for player:
AVFoundation
AVPlayer
AVPlayerLayer
The source is an AVAsset representing a remote URL
The implementation is pretty standard.
What I use for the recorder:
AVFoundation
AVCaptureDeviceInput
AVCaptureMovieFileOutput
AVCaptureVideoPreviewLayer
Again all pretty standard.

Background and foreground apps using audio

I did some preliminary test and have a good idea the answer is no. But just need to confirm: Can a background and foreground app share audio playback device? (The background app will be mine. The foreground app will be from third party)
That is possible and here is how:
Make sure that app continues playing audio when left in background by doing this:
a) add the following to your Info plist file:
"Required background modes"
"Item 0" -> "App plays audio"
b) Call setCategory:error: for AVAudioSession of your app:
NSError *setCategoryError = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError];
Allow your audio to be mixed with audio from other apps by calling AudioSessionSetProperty():
OSStatus propertySetError = 0;
UInt32 allowMixing = true;
propertySetError = AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers,
sizeof (allowMixing),
&allowMixing
);
You will need to link against AVFoundation and AudioToolbox frameworks for this code.
Technically this is possible. While a background app is playing music, the foreground app is still allowed to play sound effects (like the "Music" app is playing music while you hear the sound effects of the game you're playing foreground). So you could declare the music a foreground app plays as a sound effect while another app plays music in background.
But if you can't control the foreground app, to get them play their music as a sound effect, than there is no way.
I also doubt that an app that declared continuos music a sound effect will make it through Apple review process.

How do I stop AirPlay audio with AVPlayer?

I'm working on an iOS app that, for reasons we won't get into here, wants to sometimes disable AirPlay playback on a remote device, and only play video locally on the iOS device, regardless of the user's settings.
I'm using AVPlayer to play the video, and that's currently non-negotiable.
I'm setting the iOS 5.0+ AVPlayer property allowsAirPlayVideo to NO, which prevents the video from playing remotely. But if the user has turned on AirPlay on the iOS device, the audio is still streamed through the remote device.
I don't see a comparable allowsAirPlayAudio flag in Apple's documentation, nor have I found mention of this issue anywhere else.
For example, this Stack Overflow question:
Audio Output Routes for AirPlay
talks about "audio output destinations in a USB audio accessory", which doesn't sound like what I need.
I don't want to just turn off audio, I want the audio to keep being played through my iOS device.
Am I missing something? Thanks!
Possible a duplicate of How to detect if a bluetooth headset plugged or not IOS 8?
I know it's an old question, but hey, it may help some one
This is what I do to disconnect the audio, mConnectDisconnect is boolean parameter.
allowsExternalPlayback will remove the image from airplay and play it on your device screen.
AVAudioSessionCategoryOptionDefaultToSpeaker this option will let you change audio to the device
AVAudioSession* session = [AVAudioSession sharedInstance];
self.player.allowsExternalPlayback = mConnectDisconnect;
if(allowsExternalPlayback){
[session setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionAllowAirPlay error:nil];
}else{
[session setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];
}
[session setActive:true error:nil];
}

iPhone - AVAudioSession - AVAudioRecorder - issues when device sleeps

I'm trying to figure out how to keep AVAudioRecorder recording even if the device goes to sleep (or to keep the device from going to sleep to begin with).
According to this question I just need to add a category to the AVAudioSession, but that doesn't seem to be working.
I also found MMPDeepSleepPreventer but every time it plays a silent sound it interrupts the recording.
So is there a way to get AVAudioRecorder to continue recording after the device sleeps. OR is there a way to stop the device from sleeping in the first place?
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:NULL];
You can stop the device from sleeping by adding
[UIApplication sharedApplication].idleTimerDisabled = YES;
But I am not sure whether Apple encourage using this.

Resources