Маршрутизация iPhone Аудио Звук - PullRequest
5 голосов
/ 09 сентября 2010

У меня есть приложение, которое одновременно слушает и воспроизводит звук.По умолчанию звук выводится через наушники.Поэтому я использую следующий код для маршрутизации через динамик:

UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);

Это прекрасно работает.Но теперь я хотел бы направить звук через наушники, когда подключены наушники или внешние динамики.Как бы мне этого добиться?

Также в идеале все остальные звуки (например, музыка и т. Д.) Должны быть отключены при запуске приложения.

Ответы [ 3 ]

11 голосов
/ 09 сентября 2010

Для этого вы должны добавить прослушиватель свойства при настройке аудио сеанса:

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

Поэтому, когда наушники подключены или отключены, вы получаете уведомление и меняете направление вывода звука.

1 голос
/ 28 декабря 2012

Это быстрый и грязный способ, и мне кажется, что он работает:

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);
      }
    }
  }
}
0 голосов
/ 23 октября 2015

Поскольку AudioSessionSetProperty устарела с iOS 7, мы должны использовать AVFoundation AVAudioSession. Поскольку желаемое действие - разрешить пользовательскому действию переопределить маршрут через динамик, вы можете рассмотреть разницу между AVAudioSessionPortOverrideSpeaker и AVAudioSessionCategoryOptionDefaultToSpeaker.

Согласно Техническому бюллетеню Q & A QA1754: «При использовании AVAudioSessionCategoryOptionDefaultToSpeaker жесты пользователя будут учитываться. Например, подключение гарнитуры приведет к изменению маршрута на микрофон / наушники гарнитуры, а отключение гарнитуры приведет к изменению маршрута на встроенный микрофон / динамик ".

Обратите внимание, что в техническом бюллетене объясняется, что AVAudioSessionPortOverrideSpeaker будет более подходящим для использования, например, с кнопкой громкой связи, а это не то, о чем просил оригинальный пост.

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

Также этот вопрос похож на вопрос, рассмотренный в другом, но связанном посте.

В соответствии с тем же техническим бюллетенем, упомянутым здесь: «Подумайте об использовании overrideOutputAudioPort: с точки зрения того, что вы могли бы использовать для реализации кнопки громкой связи, где вы хотите иметь возможность переключения между динамиком (AVAudioSessionPortOverrideSpeaker) и обычным выходным маршрутом AVAudioSessionPortOverrideNone). "

Обратитесь к этому сообщению, если вы ищете реализацию категории overrideOutputPort override динамика: Как маршрутизировать звук на динамик без использования AudioSessionSetProperty?

...