2011-10-27 13 views
8

Estaba tratando de averiguar qué sucede realmente durante semanas y no tengo idea de por qué no puedo continuar la reproducción después de la interrupción, por lo que probablemente ustedes conozcan una respuesta. AudioSessionSetActive (TRUE) siempre devuelve '! Cat' que es kAudioSessionIncompatibleCategory mientras se reactiva si mi aplicación se reproduce en segundo plano y estoy en una aplicación diferente. Aunque funciona bien y continúa la reproducción si cogí interrupción mientras estaba en mi aplicación.AudioSessionSetActive falla después de la interrupción

El código original en realidad tiene todas las llamadas AudioSession y AudioQueue envueltas en macros que imprimen OSStatus si eso significa un error, pero lo eliminé para una mejor legibilidad. Además, [self pause] simplemente alterna pause, por lo que básicamente llama a AudioQueueStart (audioQueue, NULL) en upause, pero no funciona, por supuesto, si AudioSession falla.

audio código de inicialización de la sesión:

AudioSessionInitialize(NULL, NULL, _audioSessionInterruptionListener, self); 
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback; 
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory); 
AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, _audioSessionPropertyListener, self); 
AudioSessionSetActive(TRUE); 

Interrupción código del controlador:

- (void)handleInterruptionChangeToState:(AudioQueuePropertyID)inInterruptionState 
{ 
    if(inInterruptionState == kAudioSessionBeginInterruption) 
    { 

     NSLog(@"+Interruption"); 

     if(self.state == NX_STATE_PLAY) 
     { 
      [self pause]; 
      AudioSessionSetActive(FALSE); 

      isPausedByInterruption = YES; 
     } 
    } 
    else if(inInterruptionState == kAudioSessionEndInterruption) 
    { 
     if(isPausedByInterruption) 
     { 
      AudioSessionSetActive(TRUE); 
      [self pause]; 

      isPausedByInterruption = FALSE; 
     } 

     NSLog(@"-Interruption"); 
    } 
} 

Este código fuente streamer se puede encontrar aquí https://bitbucket.org/and/amaudiostreamer/src/122de41fe6c0/AMAudioStreamer/AMAudioStreamer/Classes/NxAudioStreamer.m si va a ayudar de alguna manera a resolver un problema ..

Respuesta

0

Intente activar AudioSession en else si condición de la siguiente manera:

AVAudioSession *session = [AVAudioSession sharedInstance]; 
NSError *error = nil; 

[session setCategory: AVAudioSessionCategoryPlayback error: &error]; 
if (error != nil) 
    NSLog(@"Failed to set category on AVAudioSession"); 

// AudioSession and AVAudioSession calls can be used interchangeably 
OSStatus result = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, RouteChangeListener, self); 
if (result) NSLog(@"Could not add property listener! %d\n", result); 

BOOL active = [session setActive: YES error: nil]; 
if (!active) 
    NSLog(@"Failed to set category on AVAudioSession"); 

Pero creo que esto puede no funcionar debido a que en mi caso es lo que ocurrió cuando yo estaba en el fondo que no estaba recibiendo ninguna sesión. Pero intente analizar el aurioTouch example de Apple y solo pase por el archivo AppDelegate e intente analizar el método (void)rioInterruptionListener que explica el mismo problema.

¿Está utilizando Live Streaming de audio? entonces le recomendaría que revisara mi question's answer, donde un problema de inicio de cola se resuelve manejando el error como figura en mi respuesta.

Espero que esto sea útil para usted.

+0

Como esperaba, no funciona y me da el mismo error de una manera más de moda: "No se pudo establecer la categoría en AVAudioSession. La operación no se pudo completar. (OSStatus error 560161140.)". Trataré de analizar rioInterruptionListener .. Creo que me perdí algo pequeño. – Andy

+0

entonces creo que primero debes probar la cosa en la respuesta de mi pregunta. Pero aquí será demasiado difícil para obtener el problema exacto. Debe identificar dónde 'exactamente' desea modificar el código. esto fue un desafío para mí cuando lo hice ... Mejor suerte para ti ... Espero que puedas resolver el problema ... – DShah

0

kAudioSessionEndInterruption puede afectar o no su código, no es una forma confiable de controlar sus estados de reproducción, simplemente no apague la sesión de audio en su código, reanudará la sesión una vez que pueda obtener control nuevamente, en su caso, simplemente comente que AudioSessionSetActive (FALSE) lo ayudará.

+0

Entiendo tu punto, pero no me ayuda a obtener la sesión de audio volver atrás y continuar la reproducción :( – Andy

0

Si nos fijamos en Listing 7-16 An interruption listener callback function en el Audio Session Programming Guide cookbook section, el ejemplo de código (que parece ser compatible con su situación, usando kAudioSessionCategory_MediaPlayback) no realiza realmente la llamada

AudioSessionSetActive(FALSE); 

en el caso de kAudioSessionBeginInterruption, y la llamada

AudioSessionSetActive(TRUE); 

en el caso de kAudioSessionEndInterruption. Realmente no creo que debas estar haciendo esto. This post parece ilustrar este problema también (obtener una kAudioSessionIncompatibleCategory). ¿Qué sucede si comenta estas dos llamadas?

La razón por la cual el problema ocurre cuando su aplicación en el fondo, no en el primer plano es un misterio. Quizás deberías rastrear el estado (como parece que estás haciendo con NX_STATE_PLAY), y luego tener dos métodos diferentes ([self pause] y [self play]), ya que tal vez el [self pause] (alternar el estado de reproducción) se llamará cantidad inesperada de veces.

+0

[pausa propia] llamada solo dos veces, así que básicamente AudioQueuePause en el inicio de interrupción y AudioQueueStart en interrupción final, lo revisé, no hay problemas allí. Eliminé AudioSessionSetActive (FALSE) de mi código y sigo recibiendo estas cosas en mi registro:. VERIFY_OSS AudioSessionSetActive (verdadero) - '! gato' VERIFY_OSS AudioQueueStart (audioQueue, NULL) - -12.985 – Andy

0

Lo entendí de alguna manera, puede probar su riesgo.

En la función

void _audioSessionInterruptionListener(void *inClientData, UInt32 inInterruptionState) 

eliminar

[(NxAudioStreamer*)inClientData handleInterruptionChangeToState:inInterruptionState]; 

hay necesidad de llamar handleInterruptionChangeToState cuando se puede manejar directamente en audioSessionInterruptionListeneraudioSessionInterruptionListener porque tiene inInterruptionState como parámetro. Así modificar a audioSessionInterruptionListener

void _audioSessionInterruptionListener(void *inClientData, UInt32 inInterruptionState) 
{ 
    if(inInterruptionState == kAudioSessionBeginInterruption) 
    { 

        NSLog(@"+Interruption"); 

        if(self.state == NX_STATE_PLAY) 
        { 
            [self pause]; 
            AudioSessionSetActive(FALSE); 

            isPausedByInterruption = YES; 
        } 
    } 
    else if(inInterruptionState == kAudioSessionEndInterruption) 
    { 
        if(isPausedByInterruption) 
        { 
            AudioSessionSetActive(TRUE); 
            [self pause]; 

            isPausedByInterruption = FALSE; 
        } 

        NSLog(@"-Interruption"); 
    } 
} 
+0

creo que di por vencido en esto y utilizar AVFoundation desde iOS 3 no es importante para mí más Gracias por respuesta de todos modos. – Andy

3

Si está utilizando la API AudioQueue lo que necesita hacer algunos pasos adicionales que depende de algunos factores. Nunca he hecho eso, así que dejaré la explicación al experto:
hay un video sobre ese tema en el sitio web de desarrolladores de Apple que cubre ese problema exacto. WWDC 2010 sesión 412 Desarrollo de audio para iPhone OS parte 1 alrededor de los 45 minutos tienes una explicación bastante buena sobre ese asunto.

+0

Todavía no entiendo por qué AudioSessionSetActive (verdadero); devuelve! cat, probablemente ni siquiera importa lo que devuelve, todo lo que tengo que hacer es continuar la reproducción. Así que, básicamente, tengo que deshacerme y volver a crear AudioQueue mientras uso el códec de hardware. Esto es muy importante, gracias por tu respuesta. – Andy

+0

Hay mucho en ese video, si mal no recuerdo hay una sección en la categoría AudioSession, tal vez allí encontrará algo. –

2

Tuve un problema, cuando la alarma se presenta durante la ejecución de la aplicación, el usuario solo presiona el botón de encendido del dispositivo para que se ponga en reposo. Luego, después de reanudar mi sueño, mi AudioSessionSetActive falla con algo así como "this audiosession type can't be used". Traté de agregar set audiosession propiedad antes de AudioSessionSetActive(true) en Interruptionlistener, pero no tuve suerte. Finalmente añade

retry(~1000 times :) 

FTW)

AudioSessionSetActive(true), 

y se resolvió mi problema.

+0

Creo que no me las arreglé por completo para hacer que funcione esos días, fue un comportamiento bastante aleatorio. Más tarde cambié a AVFoundation y AVSession que parece funcionar. Honestamente, creo que Apple tenía errores en su SDK y creo que este código funcionaría correctamente en iOS 6, pero es solo una suposición. – Andy

Cuestiones relacionadas