Вопрос

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

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?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top