How do I stop AirPlay audio with AVPlayer? - ios

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];
}

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.

App ported to iOS 7 now requests microphone access

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);

Audio triggered by background location

Target OS: iOS 6+
Devices: Phones only
I'm creating an fairly simple locative media app. The one technical difficulty I'm having is whether or not I can do what I want with background audio.
I receive GPS location updates successfully in the background but I would like to use these to trigger audio on region entry. The app does not play audio constantly in foreground, only on entry to these fences.
Does the 'playing silence' trick still work to keep the Audio Session and is this an app where Apple would tolerate its use? If so could anyone provide recently functional code for it?
If you set up your application to also enable background audio, in application:didFinishLaunching: like so:
[[AVAudioSession sharedInstance] setDelegate: self];
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
and add audio as a background mode in the app's plist file, your app will keep on running in the background and play sounds when it wishes (e.g. when a location change has happened). However, I think you have to close the application while playing sound.
However, there might be an issue with this, because background audio is meant for apps that actually keep running a track/stream in the background. I could see how Apple might reject your app for using their API in an unintended way. So this is the problem with the playing silence trick.
Also, another problem could be that if the user goes out of your app, then starts playing their music through Music or any other music app (Spotify, a radio app etc.) that has access to background audio, your application's audio permissions will be disabled (your app won't be able to play sound anymore through the audio framework, because another app has taken control of the background audio).
An option I would recommend: throw a local notification with your own sound when the user changes location:
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
localNotif.soundName = #"your-sound-file-name";

Play video in UIWebview background on Airplay

I have an app that plays several webvideos like Youtube and Vimeo in a UIWebView. When the video plays it is possible to send it to an Apple TV over AirPlay.
Currently, during playback over AirPlay the video stops when I pause the app and move it to the background.
My desired result is that the video will keep playing on the Apple TV.
After some research I found out that I have to set the Required background modes in the Info.plist to App plays audio. Unfortunately this did not work.
So what does need to be set to keep the video playing over AirPlay when the app is moved to the background.
i've tested this on iOS6 with UIWebView loading video webpage, and it does the job. the audio session needed to be set as AVAudioSessionCategoryPlayback in order to be played in background.
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];

Resources