Подтвердить что ты не робот

Обнаруживать, если наушники (не микрофон) подключены к устройству iOS

Мне нужно изменить свой звук в зависимости от того, подключены ли наушники. Я знаю, что kAudioSessionProperty_AudioInputAvailable, который скажет мне, есть ли микрофон, но я бы хотел протестировать любые наушники, а не только наушники с встроенный микрофон. Возможно ли это?

4b9b3361

Ответ 1

Вот мой собственный метод, который является слегка измененной версией, найденной на этом сайте: 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;
}

Ответ 2

Здесь решение, основанное на комментарии rob mayoff:

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

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

Просто ссылку на структуру AVFoundation.

Ответ 3

Просто голова для любых будущих читателей этого сообщения.

Большинство методов AVToolbox устарели с выпуском iOS 7 без альтернативы, поэтому прослушиватели аудио теперь в значительной степени избыточны

Ответ 4

Я начал с кода, приведенного выше jpsetung, но было несколько проблем с ним для моего варианта использования:

  • Нет никаких доказательств того, что называется kAudioSessionProperty_AudioRoute в документах
  • Утечки route
  • Нет проверки аудио сессии
  • Проверка строки для наушников вместо логической осведомленности категорий
  • Меня больше интересовало, использует ли iPhone свои динамики, а "наушники" означают "ничего, кроме динамиков". Я чувствую, что отказ от таких параметров, как "bluetooth", "airplay" или "lineout" был опасным.

Эта реализация расширяет проверку, чтобы разрешить любой тип указанного вывода:

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

Используется так:

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