Список доступных выходных аудио-целей AVAudioSession

Мне нужно перечислить аудиовыходы, доступные для приложения iOS. Мой вопрос аналогичен этому: как перечислить доступный маршрут вывода аудио на iOS

Я пробовал этот код:

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

Однако я всегда вижу только один выходной порт (число равно 1), также, если у меня есть два (Airplay и встроенный динамик). Если я использую приложение «Музыка», я могу видеть оба порта и переключаться между ними. В моем приложении я вижу только тот, который я выбрал.

Есть что-то еще, что мне нужно сделать?

спасибо

РЕДАКТИРОВАТЬ:

Я тоже пробовал этот код:

 CFDictionaryRef asCFType = nil; UInt32 dataSize = sizeof(asCFType); AudioSessionGetProperty(kAudioSessionProperty_AudioRouteDescription, &dataSize, &asCFType); NSDictionary *audioRoutesDesc = (__bridge NSDictionary *)asCFType; NSLog(@"audioRoutesDesc %@", audioRoutesDesc); 

но словарь содержит только один выход. Кроме того, массив входных источников пуст (у меня есть iPhone 4s)

EDIT2:

У меня что-то работает с помощью MPVolumeView. Этот компонент имеет кнопку, которая позволяет выбирать выходной аудиомаршрут, например, в приложении «Музыка».

Если вы хотите, вы можете скрыть ползунок (и иметь только кнопку), используя:

 self.myMPVolumeView.showsVolumeSlider = NO; 

Попробуйте что-то вроде этого, его больше, чем вам нужно, но вы можете его обмануть:

  + (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) { } 

Это будет зависеть от вашей категории AVAudioSession.

Вы можете спокойно предположить на iPhone, что у вас есть как минимум микрофон в качестве входа, а динамик – как выход. Если вы пытаетесь получить список выходов Bluetooth / AirPlay, сначала вам нужно убедиться, что ваша категория сеансов сообщает об этом вам:

 do { try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord, withOptions: .AllowBluetooth) try audioSession.setActive(true) } catch let e { debugPrint("failed to initialize audio session: \(e)") } 

Тогда неинтуитивный способ получения выходных данных – это проверить AVAudioSession.availableInputs поскольку, как правило, устройство HFP с Bluetooth будет иметь микрофон тоже. Возможно, сейчас я буду принимать на себя много нового. Но это единственный способ последовательно получать ваши доступные вызовы.

Лучше всего использовать категорию MultipleRoute, которая даст вам больше свободы при доступе к AVAudioSessionPort

Interesting Posts
Давайте будем гением компьютера.