2010-09-16 24 views
14

Muszę zmienić dźwięk w zależności od tego, czy słuchawki są podłączone. Jestem świadomy kAudioSessionProperty_AudioInputAvailable, który powie mi, czy jest mikrofon, ale Chciałbym przetestować wszystkie słuchawki, nie tylko słuchawki z wbudowanym mikrofonem. czy to możliwe?Wykryj, czy słuchawki (nie mikrofon) są podłączone do urządzenia z systemem iOS.

+1

@Brad Larson Odpowiedź na to pytanie nie dostarczyła mi potrzebnych informacji. Moje pytanie określa _headphones_, nie mikrofon. Uważam, że zaakceptowana odpowiedź na pytanie, które łączysz, opisuje, jak wykryć, czy mikrofon jest podłączony. – morgancodes

+0

Tak, domyślam się, że pytasz o udoskonalenie tego pytania, gdy proste wykrycie wejścia audio nie jest wystarczająco dobre. Być może część dyskusji wokół [tego pytania] (http://stackoverflow.com/questions/1238758/how-can-i-detect-if-headphones-are-connected-to-an-ipod-touch-g1) może bądź pomocny również. –

+0

Dzięki za skierowanie mnie na to pytanie. – morgancodes

Odpowiedz

28

Oto metoda mój własny, który jest lekko zmodyfikowana wersja jednego znaleźć na tej stronie: http://www.iphonedevsdk.com/forum/iphone-sdk-development/9982-play-record-same-time.html

- (BOOL)isHeadsetPluggedIn { 
    UInt32 routeSize = sizeof (CFStringRef); 
    CFStringRef route; 

    OSStatus error = AudioSessionGetProperty (kAudioSessionProperty_AudioRoute, 
               &routeSize, 
               &route); 

    /* Known values of route: 
    * "Headset" 
    * "Headphone" 
    * "Speaker" 
    * "SpeakerAndMicrophone" 
    * "HeadphonesAndMicrophone" 
    * "HeadsetInOut" 
    * "ReceiverAndMicrophone" 
    * "Lineout" 
    */ 

    if (!error && (route != NULL)) { 

     NSString* routeStr = (NSString*)route; 

     NSRange headphoneRange = [routeStr rangeOfString : @"Head"]; 

     if (headphoneRange.location != NSNotFound) return YES; 

    } 

    return NO; 
} 
+0

to po prostu nie działa :(troska o aktualizację odpowiedzi? – binnyb

+0

co nie działa? Nie kompiluje? Używam tego fragmentu kodu w grze i działa dla mnie – jptsetung

+0

NO jest zawsze zwracane niezależnie jeśli moje słuchawki są podłączone – binnyb

1

zacząłem z kodem podanym powyżej przez jpsetung, ale było kilka problemów z nim dla mojego przypadku użycia:

  • Brak dowodów na coś, co nazywa kAudioSessionProperty_AudioRoute w docs
  • Wycieki route
  • Nie sesja dźwięku check
  • check String dla słuchawek zamiast logicznego świadomości kategoriach
  • byłem bardziej zainteresowany czy iPhone używał swoich głośników z „słuchawkami”, czyli „coś innego niż głośniki”. Uważam, że pominięcie opcji takich jak "bluetooth", "airplay" czy "lineout" było niebezpieczne.

Ta implementacja rozszerza kontrolę, aby umożliwić wszelkiego rodzaju określonego wyjścia:

BOOL isAudioRouteAvailable(CFStringRef routeType) 
{ 
    /* 
    As of iOS 5: 
    kAudioSessionOutputRoute_LineOut; 
    kAudioSessionOutputRoute_Headphones; 
    kAudioSessionOutputRoute_BluetoothHFP; 
    kAudioSessionOutputRoute_BluetoothA2DP; 
    kAudioSessionOutputRoute_BuiltInReceiver; 
    kAudioSessionOutputRoute_BuiltInSpeaker; 
    kAudioSessionOutputRoute_USBAudio; 
    kAudioSessionOutputRoute_HDMI; 
    kAudioSessionOutputRoute_AirPlay; 
    */ 

    //Prep 
    BOOL foundRoute = NO; 
    CFDictionaryRef description = NULL; 

    //Session 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     AudioSessionInitialize(NULL, NULL, NULL, NULL); 
    }); 

    //Property 
    UInt32 propertySize; 
    AudioSessionGetPropertySize(kAudioSessionProperty_AudioRouteDescription, &propertySize); 
    OSStatus error = AudioSessionGetProperty(kAudioSessionProperty_AudioRouteDescription, &propertySize, &description); 
    if (!error && description) { 
     CFArrayRef outputs = CFDictionaryGetValue(description, kAudioSession_AudioRouteKey_Outputs); 
     CFIndex count = CFArrayGetCount(outputs); 
     if (outputs && count) { 
      for (CFIndex i = 0; i < count; i++) { 
       CFDictionaryRef route = CFArrayGetValueAtIndex(outputs, i); 
       CFStringRef type = CFDictionaryGetValue(route, kAudioSession_AudioRouteKey_Type); 
       NSLog(@"Got audio route %@", type); 

       //Audio route type 
       if (CFStringCompare(type, routeType, 0) == kCFCompareEqualTo) { 
        foundRoute = YES; 
        break; 
       } 
      } 
     } 
    } else if (error) { 
     NSLog(@"Audio route error %ld", error); 
    } 

    //Cleanup 
    if (description) { 
     CFRelease(description); 
    } 

    //Done 
    return foundRoute; 
} 

Używane tak:

if (isAudioRouteAvailable(kAudioSessionOutputRoute_BuiltInSpeaker)) { 
    //Do great things... 
} 
+2

Zapoznaj się z '- [AVAudioSession currentRoute]' dla interfejsu Objective-C z tymi informacjami od iOS 6.0. –

+0

Zdecydowanie dobra uwaga, ale tylko jeśli łączysz się z AVFoundation (powyższy kod dotyczy AudioToolbox) – SG1

3

tylko heads up dla przyszłych czytelników tego postu.

Większość metod AVToolbox były przestarzałe wraz z wydaniem iOS 7 bez alternatywnych słuchaczy tak audio są obecnie w dużej mierze redundancji

12

Oto rozwiązanie oparte na komentarz rob mayoff za:

- (BOOL)isHeadsetPluggedIn 
{ 
    AVAudioSessionRouteDescription *route = [[AVAudioSession sharedInstance] currentRoute]; 

    BOOL headphonesLocated = NO; 
    for(AVAudioSessionPortDescription *portDescription in route.outputs) 
    { 
     headphonesLocated |= ([portDescription.portType isEqualToString:AVAudioSessionPortHeadphones]); 
    } 
    return headphonesLocated; 
} 

prostu odwołuje się do ramy AVFoundation.

+0

Świetny !!!! Działa idealnie. :) –

Powiązane problemy