2010-08-11 11 views
31

Actualmente estoy intentando configurar el audio de fondo para una aplicación que estoy desarrollando para iOS 4. La aplicación no tiene un reproductor de música dedicado viewController, sin embargo, a diferencia de otros archivos de audio de fondo aplicaciones como Pandora, lo que hace que la tarea sea un poco más confusa.iOS 4: Controles remotos para audio de fondo

He establecido correctamente la configuración Info.plist y tengo un objeto AVAudioPlayer en mi delegado de la aplicación al que se puede acceder desde cualquier lugar. Cuando el usuario reproduce una canción, reemplazo el AVAudioPlayer con uno nuevo inicializado con la canción y lo reproduzco. Todo esto funciona muy bien, excepto que ahora no tengo idea de cómo apoyar los eventos de control remoto.

Sobre la base de la documentación de Apple, tengo esto:

- (void)viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; 
    [self becomeFirstResponder]; 
} 

- (void)viewWillDisappear:(BOOL)animated { 
    [super viewWillDisappear:animated]; 
    [[UIApplication sharedApplication] endReceivingRemoteControlEvents]; 
    [self resignFirstResponder]; 
} 

- (BOOL)canBecomeFirstResponder { 
    return YES; 
} 

- (void)remoteControlReceivedWithEvent:(UIEvent *)event { 
    switch(event.subtype) { 
     case UIEventSubtypeRemoteControlTogglePlayPause: 
      if([iPhoneAppDelegate backgroundAudioPlayer].playing) 
       [iPhoneAppDelegate pauseBackgroundAudioPlayer]; 
      else 
       [iPhoneAppDelegate playBackgroundAudioPlayer]; 
      break; 
    } 
} 

La cosa es, ¿dónde pongo esto? La documentación de Apple parece sugerir que esto debería ir en algún controlador de visualización en alguna parte, pero mi aplicación tiene muchos controladores de vista y controladores de navegación. Siempre que trato de poner esto, por alguna razón tocar el botón Activar/Pausa en los controles remotos de la bandeja multitarea hace que la canción simplemente haga una pausa por un momento y luego reanude, o de alguna manera haga que la canción se reproduzca dos veces.

+0

¿Cómo cambió el botón reproducir/parar en la barra multitarea? –

Respuesta

19

Encontré un par de soluciones para recibir eventos de control remoto globales en los foros de desarrolladores de Apple después de un poco de búsqueda.

Una forma es crear la subclase UIWindow y anular su remoteControlReceivedWithEvent:.

La segunda forma, tal vez más agradable es la subclase UIApplication y anular sendEvent:. De esta forma, puede interceptar todos los eventos de control remoto y manejarlos allí globalmente, y no tener ningún otro respondedor que los maneje más adelante en la cadena de respuesta.

- (void)sendEvent:(UIEvent *)event { 
    if (event.type == UIEventTypeRemoteControl) { 
      // Handle event 
    } 
    else 
      [super sendEvent:event]; 
} 
+2

Ver mi comentario a la respuesta de Brian Dam Pedersen – HiveHicks

+0

Una forma aún más agradable de hacer esto es agregarlo a la aplicación UIA normal en una categoría – hypercrypt

+0

Recomendaría Brian's Answer – Mazyod

4

El segundo método no funcionó, sendEvent nunca fue llamado. Sin embargo, el primer método funcionó muy bien (subclases UIWindow).

+0

Funciona como un encanto. Quiero agregar que beginReceivingRemoteControlEvents se puede llamar dentro del delegado de la aplicación para suscribirse para el evento de control remoto. – Andy

0

No hay necesidad de subclase Ventana o reenviar eventos. Simplemente maneja desde tu controlador de vista principal. Consulte el ejemplo del Mezclador de audio (MixerHost) para obtener más información.

http://developer.apple.com/LIBRARY/IOS/#samplecode/MixerHost/Listings/Classes_MixerHostViewController_m.html

+2

El problema es que su controlador de vista principal no siempre estará en la pantalla mientras la aplicación va a segundo plano, es decir, no se convertirá en un primer respondedor si un modal está en la pantalla. – pablasso

+0

@pablasso podría ser, dependiendo de la aplicación. Pero no en todos los casos, estoy de acuerdo con eso. – slf

37

Los ejemplos de documentación son un poco engañoso, pero no hay necesidad de subclase nada en ninguna parte. El lugar correcto para poner remoteControlReceivedWithEvent: está en el delegado de la aplicación, ya que permanece en la cadena de respuesta independientemente de si la aplicación está en primer plano o no. Además, los eventos de control remoto de inicio/finalización deben basarse en si realmente necesita los eventos, no en la visibilidad de alguna vista aleatoria.

+11

Completamente correcto. Para obtener el control total de los controles remotos para su aplicación (ya sea en primer plano o en segundo plano), debe llamar a beginReceivingRemoteControlEvents en la aplicación: didFinishLaunchingWithOptions :, pero eso no es todo. Su UIApplicationDelegate comienza a recibir eventos de control remoto después de que su aplicación le dice a iOS que está reproduciendo una pista, configurando la propiedad MPNowPlayingInfoCenter nowPlayingInfo. – HiveHicks

+0

Es una gran respuesta, me quedé sin una semana. –

+0

Poner remoteControlReceivedWithEvent: en el delegado de la aplicación simplemente no funciona para mí; Tuve que ir con subclassing UIWindow. – JosephH

3

Luché con este por un tiempo y ninguna de las respuestas anteriores funcionó. El error en mi código, y espero que ayude a alguien que lea esto, fue que tenía el AudioSession configurado para mezclarlo con otros. Desea ser el reproductor de audio en primer plano para obtener eventos de control remoto. Comprobar para ver si tiene un código incorrecto así:

[[AVAudioSession sharedInstance] setDelegate: self]; 
    [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: nil]; 
    UInt32 doSetProperty = 0; 
    AudioSessionSetProperty (
          kAudioSessionProperty_OverrideCategoryMixWithOthers, 
          sizeof (doSetProperty), 
          &doSetProperty 
          ); 
    NSError *activationError = nil; 
    [[AVAudioSession sharedInstance] setActive: YES error: &activationError];  

y quitar el AudioSessionSetProperty, o cambia a 1. doSetProperty

0

Una cosa que parece influir en este comportamiento es cualquier opción de categoría que establezca para su AVAudioSession usando setCategory: withOptions: error: en lugar de simplemente setCategory: error :. En particular, a partir de la prueba y error, parece que si establece AVAudioSessionCategoryOptionMixWithOthers no obtendrá eventos de control remoto; los controles que se están reproduciendo todavía controlarán la aplicación iPod. Si configura AVAudioSessionCategoryOptionDuckOthers obtendrá eventos de control remoto, pero parece que puede haber cierta ambigüedad con respecto a qué aplicación se controla. Configurando categoryOptions a 0 o simplemente llamando a setCategory: error: funciona mejor.

Cuestiones relacionadas