【问题标题】:Detect if headphones (not microphone) are plugged in to an iOS device [duplicate]检测耳机(不是麦克风)是否插入iOS设备[重复]
【发布时间】:2011-04-13 07:53:11
【问题描述】:

我需要根据是否插入耳机来更改我的音频。我知道 kAudioSessionProperty_AudioInputAvailable,它会告诉我是否有麦克风,但我想测试任何耳机,而不仅仅是耳机内置麦克风。这可能吗?

【问题讨论】:

  • @Brad Larson 这个问题的答案没有给我我需要的信息。我的问题是耳机,而不是麦克风。我相信您链接到的问题的公认答案描述了如何检测是否插入了麦克风。
  • 是的,我想您是在对这个问题进行改进,即仅检测音频输入还不够好。或许围绕this question 的一些讨论也可能会有所帮助。
  • 感谢您指出这个问题。
  • 也许,将近两年过去了,你应该接受这个答案...?

标签: iphone ipad ios


【解决方案1】:

这是基于 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 框架。

【讨论】:

  • 太棒了!!!!工作完美。 :)
【解决方案2】:

为这篇文章的任何未来读者提个醒。

随着 iOS 7 的发布,大多数 AVToolbox 方法已被弃用,没有其他选择,因此音频侦听器现在基本上是冗余的

【讨论】:

    【解决方案3】:

    我从 jpsetung 上面给出的代码开始,但在我的用例中存在一些问题:

    • 没有证据表明文档中存在名为 kAudioSessionProperty_AudioRoute 的内容
    • 泄漏route
    • 没有音频会话检查
    • 耳机的字符串检查而不是类别的逻辑意识
    • 我更感兴趣的是 iPhone 是否使用了它的扬声器,“耳机”的意思是“除了扬声器之外的任何东西”。我觉得省略“蓝牙”、“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...
    }
    

    【讨论】:

    • 绝对是一个很好的说明,但前提是您链接到 AVFoundation(上面的代码适用于 AudioToolbox)
    【解决方案4】:

    这是我自己的一种方法,它是在本网站上找到的方法的略微修改版本: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;
    }
    

    【讨论】:

    • 这似乎不起作用:(想更新你的答案吗?
    • 什么不起作用?不编译?我在游戏中使用了这段代码,它对我有用。
    • 无论我的耳机是否插入,总是返回 NO
    • 插入耳机后,'error' 和 'route' 的值是多少?
    • 这是正常现象,只能在实际设备上使用。
    猜你喜欢
    • 1970-01-01
    • 2012-05-27
    • 1970-01-01
    • 1970-01-01
    • 2011-09-09
    • 1970-01-01
    • 1970-01-01
    • 2017-08-25
    • 2013-04-17
    相关资源
    最近更新 更多