Маршрут iPhone Audio Sound
-
01-10-2019 - |
Вопрос
У меня есть приложение, которое слушает и играет звук одновременно. По умолчанию звуковой выход проходит через наушники. Поэтому я использую следующий код для маршрута через динамик:
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);
Это работает нормально. Но сейчас я бы хотел направить звук через наушники, когда прикреплены наушники или внешние динамики. Как бы я этого добился?
Также в идеале все остальные звуки (например, музыки и т. Д.) ДОЛЖНЫ отключиться, когда приложение запускается.
Спасибо!
Решение
Для этого вам необходимо добавить слушатель свойства при настройке аудиосессии:
AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, audioSessionPropertyListener, nil);
Где
void audioSessionPropertyListener(void* inClientData, AudioSessionPropertyID inID,
UInt32 inDataSize, const void* inData) {
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
if (!isHeadsetPluggedIn())
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);
}
BOOL isHeadsetPluggedIn() {
UInt32 routeSize = sizeof (CFStringRef);
CFStringRef route;
OSStatus error = AudioSessionGetProperty (kAudioSessionProperty_AudioRoute,
&routeSize,
&route
);
if (!error && (route != NULL) && ([(NSString*)route rangeOfString:@"Head"].location != NSNotFound)) {
NSLog(@"HeadsetPluggedIn");
return YES;
}
NSLog(@"Headset_NOT_PluggedIn");
return NO;
}
Поэтому, когда наушники подключены или выберите, вы получаете уведомление и изменение направления выхода звука.
Другие советы
Это быстрый и грязный путь и, кажется, работает для меня:
void sessionPropertyListener(void * inClientData, AudioSessionPropertyID inID, UInt32 inDataSize, const void * inData){ if (inID == kAudioSessionProperty_AudioRouteChange) { CFStringRef newRoute; UInt32 size = sizeof(CFStringRef); AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &size, &newRoute); if (newRoute) { CFShow(newRoute); if (CFStringCompare(newRoute, CFSTR("ReceiverAndMicrophone"), (UInt32)NULL) == kCFCompareEqualTo)//if receiver, play through speakers { UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker; AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride); } else if (CFStringCompare(newRoute, CFSTR("HeadsetInOut"), (UInt32)NULL) == kCFCompareEqualTo)//headset { UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_None; AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride); } } } }
С аудиочувствиемetproperty устарели, поскольку IOS 7 мы должны использовать AVFoundation Avaudiosion. Поскольку желаемое действие состоит в том, чтобы позволить пользователю действий переопределить маршрут через динамик, вы могли бы рассмотреть разницу между AvaudiosondionPortPortoverDespeaker и AvaudiosionCategeryoptionDefaultTospeaker.
Согласно техническому бюллетене Q & A QA1754: «При использовании AvaudiosessionCategeryOptionDefaultFaultSeaker, пользовательские жесты будут удостоены. Например, подключение гарнитуры приведет к тому, что маршрут изменяется на MIC / наушники для гарнитуры и отключения гарнитуры, приведет к изменению маршрута на встроенный Микрофон / динамик ».
Обратите внимание, что Технический бюллетень объясняет, что AvaudiosessionPortPoverdespeaker будет более подходящим для использования с помощью кнопки громкой связи, например, не то, на что просил оригинальный пост.
https://developer.apple.com/library/ios/qa/qa1754/_index.html.
Моя собственная реализация вызывается, прежде чем я вызовуте игрока следующим образом:
NSError *error;
AVAudioSession* audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:&error];
// handle any error
// initiate the player or recorder
[_player play];
Также этот вопрос аналогичен одному адресованному в другом, но связанном посте.
Согласно тому же техническому бюллетеню, упомянутому здесь «подумайте о том, чтобы использовать перепредействующую способностьудопорт: с точки зрения того, что вы можете использовать для реализации кнопки громкой связи, где вы хотите иметь возможность переключаться между динамиком (AvaudiosonsessOverPlideSpeakeaker), а также обычный выходной маршрут (AvaudiosessionPortOverridenone). "
Обратитесь к этому посту, если вы ищете реализацию переопределения отпуска докладчика:Как направлять аудио до динамика без использования AudiOsessionsetSetProperty?