Overriding iOS Audio Output

By : zic10
Source: Stackoverflow.com
Question!

I have been doing some research for a project that I'm working on and am trying to determine if it is possible to programmatically redirect audio output. Assume that I have an audio mixer box connected to the iPhone via USB. This USB supports both audio input and output routing. I know how to "detect" if an external USB accessory is connected to the iPhone, and I know how to detect the AVAudioSession inputs and outputs. Let me post some sample code with what I understand so far.

AVAudioSessionRouteDescription *route = [[AVAudioSession sharedInstance] currentRoute];

//Check the route inputs
for( AVAudioSessionPortDescription *inputDescription in route.inputs)
{
    NSLog(@"Port Name: %@", inputDescription.portName);
    NSLog(@"Port Description: %@", inputDescription.portType);

    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Input Ports" message:[NSString stringWithFormat:@"INPUT PORT NAME NAME: %@ INPUT PORT DESCRIPTION: %@ INPUT ROUTE COUNT: %lu",inputDescription.portName, inputDescription.portType, (unsigned long)[route.outputs count]] delegate:self cancelButtonTitle:nil otherButtonTitles:@"Ok" , nil];
    [alert show];

    [self setInput:inputDescription];
}

if(route.inputs.count == 0)
{
    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Input Ports" message:@"Did not detect any input connections" delegate:self cancelButtonTitle:nil otherButtonTitles:@"Ok" , nil];

    [alert show];
}

//Check the route outputs
for( AVAudioSessionPortDescription *portDescription in route.outputs )
{ 
    NSLog(@"Port Name: %@", portDescription.portName);
    NSLog(@"Port Description: %@", portDescription.portType);

    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Output Ports" message:[NSString stringWithFormat:@"OUTPUT PORT NAME NAME: %@ OUTPUT PORT DESCRIPTION: %@ OUTPUT ROUTE COUNT: %lu",portDescription.portName, portDescription.portType, (unsigned long)[route.outputs count]] delegate:self cancelButtonTitle:nil otherButtonTitles:@"Ok" , nil];
    [alert show];   
}

I also know how to "override" iOS output so that it comes to the built in speaker instead of the headphones.

NSError *error;

AVAudioSession *session = [AVAudioSession sharedInstance];

BOOL overrideSuccess =  [session overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&error];

if(overrideSuccess)
{
    NSLog(@"Override succeeded");
}

Ideally I would like to be able to do something like this:

  1. Detect any outputs and show them to the user. (I can do this)
  2. Allow the user to "select" what output they would wish to use
  3. Override the current output route to re-direct output to the device the user wishes to use.

This final step I'm unsure if I can do.

The idea is to let users make recordings without being limited to the external microphone of the iOS device. Would appreciate any tips or advice on if what I am trying to achieve is possible. Also, I've looked through the Apple documentation extensively on this and was unable to conclude if this is 100% possible or not.

By : zic10


Answers

You can do it if you use an AVAudioSession, using the "overrideOutputAudioPort:error:" method. Here's a link to the AVAudioSession class reference: https://developer.apple.com/library/IOs/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/index.html



This video can help you solving your question :)
By: admin