Lista de audio de salida disponible AVAudioSession
objective-c airplay (3)
Dependerá de su categoría AVAudioSession.
Puede suponer de forma segura en un iPhone que tiene al menos un micrófono como entrada y un altavoz como salida. Si está tratando de obtener una lista de salidas de Bluetooth / AirPlay, primero debe asegurarse de que la categoría de su sesión le esté informando:
do
{
try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord, withOptions: .AllowBluetooth)
try audioSession.setActive(true)
}
catch let e
{
debugPrint("failed to initialize audio session: /(e)")
}
Entonces, una forma no intuitiva de obtener salidas disponibles es verificar las AVAudioSession.availableInputs
ya que generalmente un dispositivo HFP con bluetooth también tendría un micrófono ... Puede que esté asumiendo muchas cosas en este momento ... pero esa es la única manera de obtener constantemente sus salidas disponibles.
Una mejor manera es usar la categoría MultipleRoute que le dará más libertad para acceder a AVAudioSessionPort
Necesito enumerar las salidas de audio disponibles para una aplicación iOS. Mi pregunta es similar a esta: Cómo listar la ruta de salida de audio disponible en iOS
Probé este código:
NSError *setCategoryError = nil;
BOOL success = [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback
error: &setCategoryError];
NSError *activationError = nil;
[[AVAudioSession sharedInstance] setActive: YES error: &activationError];
…
NSLog(@"session.currentRoute.outputs count %d", [[[[AVAudioSession sharedInstance] currentRoute] outputs ] count]);
for (AVAudioSessionPortDescription *portDesc in [[[AVAudioSession sharedInstance] currentRoute] outputs ]) {
NSLog(@"-----");
NSLog(@"portDesc UID %@", portDesc.UID);
NSLog(@"portDesc portName %@", portDesc.portName);
NSLog(@"portDesc portType %@", portDesc.portType);
NSLog(@"portDesc channels %@", portDesc.channels);
}
Sin embargo, siempre veo un solo puerto de salida (el recuento es 1), también si tengo dos (un Airplay y un altavoz incorporado). Si uso la aplicación Música, puedo ver ambos puertos y cambiar entre ellos. En mi aplicación solo veo la que he seleccionado.
¿Hay algo más que necesito hacer?
Gracias
EDITAR:
Intenté este código, también:
CFDictionaryRef asCFType = nil;
UInt32 dataSize = sizeof(asCFType);
AudioSessionGetProperty(kAudioSessionProperty_AudioRouteDescription, &dataSize, &asCFType);
NSDictionary *audioRoutesDesc = (__bridge NSDictionary *)asCFType;
NSLog(@"audioRoutesDesc %@", audioRoutesDesc);
pero la lista del diccionario solo un destino de salida. Además, la matriz de fuentes de entrada está vacía (tengo un iPhone 4s)
EDIT2:
Tengo algo trabajando con MPVolumeView. Este componente tiene un botón que le permite elegir la ruta de salida de audio, como en la aplicación de música.
Si lo deseas, puedes ocultar el control deslizante (y tener solo el botón) usando:
self.myMPVolumeView.showsVolumeSlider = NO;
Intente algo como esto, es más de lo que necesita pero puede reducirlo:
+ (NSString *) demonstrateInputSelection
{
NSError* theError = nil;
BOOL result = YES;
NSMutableString *info = [[NSMutableString alloc] init];
[info appendString: @" Device Audio Input Hardware/n"];
NSString *str = nil;
if( iOSMajorVersion < 7 ){
str = @"No input device information available";
NSLog(@"%@",str);
[info appendFormat:@"%@/n",str];
return info;
}
AVAudioSession* myAudioSession = [AVAudioSession sharedInstance];
result = [myAudioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&theError];
if (!result)
{
NSLog(@"setCategory failed");
}
result = [myAudioSession setActive:YES error:&theError];
if (!result)
{
NSLog(@"setActive failed");
}
// Get the set of available inputs. If there are no audio accessories attached, there will be
// only one available input -- the built in microphone.
NSArray* inputs = [myAudioSession availableInputs];
str = [NSString stringWithFormat:@"/n--- Ports available on %@: %d ---", [UIDevice currentDevice].name , [inputs count]];
NSLog(@"%@",str);
[info appendFormat:@"%@/n",str];
// Locate the Port corresponding to the built-in microphone.
AVAudioSessionPortDescription* builtInMicPort = nil;
AVAudioSessionDataSourceDescription* frontDataSource = nil;
for (AVAudioSessionPortDescription* port in inputs)
{
// Print out a description of the data sources for the built-in microphone
str = @"/n**********";
NSLog(@"%@",str);
[info appendFormat:@"%@/n",str];
str = [NSString stringWithFormat:@"Port :/"%@/": UID:%@", port.portName, port.UID ];
NSLog(@"%@",str);
[info appendFormat:@"%@/n",str];
if( [port.dataSources count] ){
str = [NSString stringWithFormat:@"Port has %d data sources",(unsigned)[port.dataSources count] ];
NSLog(@"%@",str);
[info appendFormat:@"%@/n",str];
}
str = [NSString stringWithFormat:@">%@", port.dataSources];
NSLog(@"%@",str);
// [info appendFormat:@"%@/n",str];
if( [port.portType isEqualToString:AVAudioSessionPortLineIn] ){
str = @"Line Input found";
NSLog(@"%@",str);
[info appendFormat:@"%@/n",str];
}
else if( [port.portType isEqualToString:AVAudioSessionPortUSBAudio] ){
str = @"USB Audio found";
NSLog(@"%@",str);
[info appendFormat:@"%@/n",str];
}
else if ([port.portType isEqualToString:AVAudioSessionPortBuiltInMic]){
builtInMicPort = port;
str = @"Built-in Mic found";
NSLog(@"%@",str);
[info appendFormat:@"%@/n",str];
}
else if ([port.portType isEqualToString:AVAudioSessionPortHeadsetMic]){
builtInMicPort = port;
str = @"Headset Mic found";
NSLog(@"%@",str);
[info appendFormat:@"%@/n",str];
}
else{
str = @"Other input source found";
NSLog(@"%@",str);
[info appendFormat:@"%@/n",str];
}
// loop over the built-in mic''s data sources and attempt to locate the front microphone
for (AVAudioSessionDataSourceDescription* source in port.dataSources)
{
str = [NSString stringWithFormat:@"/nName:%@ (%d) /nPolar:%@ /nType:%@ /nPatterns:%@", source.dataSourceName, [source.dataSourceID intValue], source.selectedPolarPattern, port.portType, source.supportedPolarPatterns];
NSLog(@"%@",str);
[info appendFormat:@"%@/n",str];
// if ([source.orientation isEqual:AVAudioSessionOrientationFront])
// {
// frontDataSource = source;
// break;
// }
} // end data source iteration
}
str = @"/n---- Current Selected Ports ----/n";
NSLog(@"%@",str);
[info appendFormat:@"%@",str];
NSArray *currentInputs = myAudioSession.currentRoute.inputs;
// str = [NSString stringWithFormat:@"/n%d current input ports", [currentInputs count]];
// NSLog(@"%@",str);
// [info appendFormat:@"%@/n",str];
for( AVAudioSessionPortDescription *port in currentInputs ){
str = [NSString stringWithFormat:@"/nInput Port :/"%@/":", port.portName ];
NSLog(@"%@",str);
[info appendFormat:@"%@/n",str];
if( [port.dataSources count] ){
str = [NSString stringWithFormat:@"Port has %d data sources",(unsigned)[port.dataSources count] ];
NSLog(@"%@",str);
[info appendFormat:@"%@/n",str];
str = [NSString stringWithFormat:@"Selected data source:%@", port.selectedDataSource.dataSourceName];
NSLog(@"%@",str);
[info appendFormat:@"%@/n",str];
if( [port.selectedDataSource.supportedPolarPatterns count] > 0 ){
str = [NSString stringWithFormat:@"Selected polar pattern:%@", port.selectedDataSource.selectedPolarPattern];
NSLog(@"%@",str);
[info appendFormat:@"%@/n",str];
}
}
}
NSArray *currentOutputs = myAudioSession.currentRoute.outputs;
// str = [NSString stringWithFormat:@"/n%d current output ports", [currentOutputs count]];
// NSLog(@"%@",str);
// [info appendFormat:@"%@/n",str];
for( AVAudioSessionPortDescription *port in currentOutputs ){
str = [NSString stringWithFormat:@"/nOutput Port :/"%@/":", port.portName ];
NSLog(@"%@",str);
[info appendFormat:@"%@/n",str];
if( [port.dataSources count] ){
str = [NSString stringWithFormat:@"Port has %d data sources",(unsigned)[port.dataSources count] ];
NSLog(@"%@",str);
[info appendFormat:@"%@/n",str];
str = [NSString stringWithFormat:@"Selected data source:%@", port.selectedDataSource.dataSourceName];
NSLog(@"%@",str);
[info appendFormat:@"%@/n",str];
}
}
// str = [NSString stringWithFormat:@"/Current Route: %@ Source:%@/n", myAudioSession.currentRoute.portName, myAudioSession.preferredInput.selectedDataSource.dataSourceName];
// NSLog(@"%@",str);
// [info appendFormat:@"%@/n",str];
if( myAudioSession.preferredInput.portName ){
str = [NSString stringWithFormat:@"/nPreferred Port: %@ Source:%@/n", myAudioSession.preferredInput.portName, myAudioSession.preferredInput.selectedDataSource.dataSourceName];
} else {
str = @"/nNo Preferred Port set";
}
NSLog(@"%@",str);
[info appendFormat:@"%@/n",str];
return info;
if (frontDataSource)
{
NSLog(@"Currently selected source is /"%@/" for port /"%@/"", builtInMicPort.selectedDataSource.dataSourceName, builtInMicPort.portName);
NSLog(@"Attempting to select source /"%@/" on port /"%@/"", frontDataSource, builtInMicPort.portName);
// Set a preference for the front data source.
theError = nil;
result = [builtInMicPort setPreferredDataSource:frontDataSource error:&theError];
if (!result)
{
// an error occurred. Handle it!
NSLog(@"setPreferredDataSource failed");
}
}
// Make sure the built-in mic is selected for input. This will be a no-op if the built-in mic is
// already the current input Port.
theError = nil;
result = [myAudioSession setPreferredInput:builtInMicPort error:&theError];
if (!result)
{
// an error occurred. Handle it!
NSLog(@"setPreferredInput failed");
}
return info;
}
AVAudioSessionRouteDescription *currentRoute = [[AVAudioSession sharedInstance] currentRoute];
for (AVAudioSessionPortDescription *output in currentRoute.outputs) {
}