Мне нужно изменить свой звук в зависимости от того, подключены ли наушники. Я знаю, что kAudioSessionProperty_AudioInputAvailable, который скажет мне, есть ли микрофон, но я бы хотел протестировать любые наушники, а не только наушники с встроенный микрофон. Возможно ли это?
Обнаруживать, если наушники (не микрофон) подключены к устройству iOS
Ответ 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...
}