Pregunta

Tengo una aplicación que no hace escuchar y reproduce el sonido al mismo tiempo. Por defecto, la salida de sonido pasa a través de los auriculares. Así que uso el siguiente código de ruta es a través del altavoz:

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

Esto funciona bien. Pero ahora, me gustaría dirigir el sonido a través de los auriculares cuando se unen auriculares o altavoces externos. ¿Cómo iba a lograr eso?

Lo ideal sería que todos los demás sonidos (música es decir, etc.) debe silenciar cuando se lance la aplicación.

Gracias!

¿Fue útil?

Solución

Para hacer esto hay que añadir que escucha la propiedad cuando sesión de audio configuración:

AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, audioSessionPropertyListener, nil);

Donde

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

Así que cuando se enchufan los auriculares o salida recibirá una notificación y cambiar la dirección de salida de audio.

Otros consejos

Esta es una manera rápida y sucia y parece que funciona para mí:

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

Con AudioSessionSetProperty obsoleta desde iOS 7 debemos utilizar AVFoundation AVAudioSession. Dado que la acción deseada es permitir una acción del usuario para anular la ruta a través del altavoz usted podría considerar la diferencia entre AVAudioSessionPortOverrideSpeaker y AVAudioSessionCategoryOptionDefaultToSpeaker.

De acuerdo con el Boletín Técnico Q y A QA1754: "Al utilizar AVAudioSessionCategoryOptionDefaultToSpeaker, será honrado gestos del usuario, por ejemplo, conectar un auricular hará que la ruta al cambio de micrófono auricular / auriculares y desconectar los auriculares hará que la ruta para cambiar a. micrófono incorporado / altavoz".

Tenga en cuenta que el boletín técnico explica que AVAudioSessionPortOverrideSpeaker sería más apropiado para su uso con un botón del altavoz, por ejemplo, que no es lo que el post original estaba pidiendo.

https://developer.apple.com/library/ios /qa/qa1754/_index.html

Mi propia aplicación se llama antes de invocar el jugador de la siguiente manera:

NSError *error;
AVAudioSession* audioSession   = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:&error];
// handle any error
// initiate the player or recorder
[_player play];

También esta pregunta es similar a una dirigida en un post diferente pero relacionado.

De acuerdo con el mismo boletín técnico mencionado aquí "pensar en usar overrideOutputAudioPort: en términos de lo que se podría utilizar para implementar un botón de altavoz en la que desea ser capaz de alternar entre el altavoz (AVAudioSessionPortOverrideSpeaker) y la ruta de salida normal ( AVAudioSessionPortOverrideNone). "

Consulte a ese puesto si usted está buscando para la aplicación de la categoría de contraorden overrideOutputPort altavoz: ¿Cómo puedo Transmisión de audio a Altavoz sin utilizar AudioSessionSetProperty

scroll top