2013-03-26 13 views
21

Muszę wyświetlić listę wyjść audio dostępnych dla aplikacji iOS. Moje pytanie jest podobne do tego: How to list available audio output route on iOSLista dostępnych wyjściowych docelowych audio AVAudioSession

Próbowałem ten kod:

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

Jednak zawsze widzę tylko jeden port wyjściowy (liczba wynosi 1), a także, jeśli mam dwie (an Airplay oraz Wbudowany głośnik). Jeśli używam aplikacji Muzyka, widzę oba porty i przełączam się między nimi. W mojej aplikacji widzę tylko tę, którą wybrałem.

Jest jeszcze coś, co muszę zrobić?

Dziękuję

EDIT:

Próbowałem ten kod, za:

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

ale lista słowniku zaledwie jeden docelowych wyjściowe. Ponadto tablica jest pusta źródeł sygnału (mam iPhone 4s)

EDIT2:

mam coś działa używając MPVolumeView. Ten komponent ma przycisk, który pozwala wybrać wyjściową trasę audio, tak jak w aplikacji Music.

Jeśli chcesz, możesz ukryć suwak (i ​​mają tylko przycisk) przy użyciu:

self.myMPVolumeView.showsVolumeSlider = NO; 

Odpowiedz

2

Spróbuj coś takiego, jej więcej niż trzeba, ale można pare go:

+ (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; 
} 
+0

Choć nieco pomocny, to nie jest odpowiedź na pytanie, jak pokazać wyjść _available_, jak to pokazuje tylko wyjść _current_ . Wygląda na to, że obecnie jedynym sposobem na wyświetlenie listy dostępnych wyjść jest dostarczony przycisk trasy "MPVolumeView". – Stuart

+0

Czy istnieje możliwość wyboru źródła wyjściowego po wybraniu źródła wejściowego? Nie mogę tego zrobić. –

1
AVAudioSessionRouteDescription *currentRoute = [[AVAudioSession sharedInstance] currentRoute]; 
    for (AVAudioSessionPortDescription *output in currentRoute.outputs) { 

    } 
1

Zależy to od kategorii AVAudioSession.

Możesz bezpiecznie założyć na iPhonie, że masz co najmniej mikrofon jako wejście i głośnik jako wyjście. Jeśli starasz się uzyskać listę Bluetooth wyjść/AirPlay, najpierw trzeba by upewnić się, że kategoria sesja jest zgłaszanie ich do ciebie:

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

Następnie non-intuicyjny sposób, żeby wyjść jest dostępne aby sprawdzić AVAudioSession.availableInputs, ponieważ zwykle urządzenie HFP z bluetooth miałoby też mikrofon. Mogę teraz dużo przypuszczać ... ale to jedyny sposób, aby konsekwentnie uzyskać dostępną przepustowość.

Lepszym sposobem jest użycie kategorię MultipleRoute który daje większą swobodę w dostępie AVAudioSessionPort

Powiązane problemy