2012-07-18 16 views
8

He habilitado correctamente el audio de fondo para mi aplicación (en la lista). Reproducir la siguiente pista una vez que se completa la corriente con SPPlaybackManager en segundo plano (cuando el teléfono está bloqueado/apagado) no funciona.Audio de fondo con cocoalibspotify

Cuando la pista actual finaliza y el audio se detiene, la aplicación no comenzará a reproducir la siguiente pista hasta que el teléfono esté desbloqueado y mi aplicación vuelva a estar activa.

¿Cómo puedo solucionar esto? Aquí hay un fragmento de código que estoy usando para comenzar a reproducir la siguiente pista. Observé que la pista actual se vuelve nula, y luego comienzo a reproducir la siguiente pista. El registro me muestra que la siguiente pista actual se está configurando en el objeto del administrador de reproducción, pero desafortunadamente está en silencio.

- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 



    if([keyPath isEqualToString:@"spotifyPlaybackManager.currentTrack"]){ 

     NSLog(@"%@ %@",keyPath,self.spotifyPlaybackManager.currentTrack); 

     if(self.spotifyPlaybackManager.currentTrack==nil && self.mode == PlayerModeSpotify){ 

      NSLog(@"PLAY NEXT"); 
      [self.spotifyPlaybackManager playTrack:self.nextSPTrack callback:^(NSError *error){ 
       if(error) TKLog(@"Spotify Playback Error %@",error); 
      }]; 
     } 
     [[NSNotificationCenter defaultCenter] postNotificationName:PlayerNowPlayingItemDidChange object:self]; 
     return; 
    } 



    [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; 
} 

Consola:

spotifyPlaybackManager.currentTrack (null) 
PLAY NEXT 
spotifyPlaybackManager.currentTrack <SPTrack: 0x60f8390>: Karaoke 

Respuesta

-2

CocoaLibSpotify hace un montón de trabajo para comenzar a reproducir la pista y es probable que se generan nuevas roscas internas en el proceso. Dudo que esto esté permitido en el estilo de audio de fondo, por lo que es probable que deba iniciar una tarea de fondo temporal para cambiar las pistas.

+0

Intenté poner 'beginBackgroundTaskWithExpirationHandler' directamente antes de llamar a 'self.spotifyPlaybackManager playTrack: ...' y el código suspende la ejecución tan pronto como se intenta crear una nueva tarea. ¿Cualquier otra sugerencia? – devinross

+0

Mi aplicación de audio (GroovePond) realiza muchas tareas en segundo plano al reproducir audio de fondo, como aceptar nuevos clientes y actualizar el estado de los clientes existentes, y Apple no parece tener ningún problema con ello. Creo que porque las tareas están directamente relacionadas con la reproducción de audio, están permitidas. – Dermot

8

La solución es muy simple pero tardé un año en darme cuenta. Mi solución anterior era comenzar una tarea en segundo plano justo antes de que terminara la pista anterior, y mantenerla en funcionamiento hasta que se reproduciera la siguiente pista. Eso fue muy propenso a errores. En cambio:

Mantenga un registro de su estado de reproducción (en reproducción o en pausa). Cuando hagas la transición a Jugar, comienza una tarea en segundo plano. Nunca lo detengas, a menos que pases a En pausa. Mantenga el estado como Reproducción incluso entre pistas. Siempre que tenga el modo de fondo de audio en su info.plist y el audio esté en reproducción, su tarea de fondo tendrá un tiempo de espera infinito.

Algunos pseudo código:

@interface PlayController 
@property BOOL playing; 

- (void)playPlaylist:(SPPlaylist*)playlist startingAtRow:(int)row; 
@end 

@implementation PlayController 
- (void)setPlaying:(BOOL)playing 
{ 
    if(playing == _playing) return; 
    _playing = playing; 

    UIApplication *app = [UIApplication sharedApplication]; 
    if(playing) 
     self.playbackBackgroundTask = [app beginBackgroundTaskWithExpirationHandler:^ { 
      NSLog(@"Still playing music but background task expired! :("); 
        [app endBackgroundTask:self.playbackBackgroundTask]; 
       self.playbackBackgroundTask = UIBackgroundTaskInvalid; 
      }]; 
    else if(!playing && self.playbackBackgroundTask != UIBackgroundTaskInvalid) 
     [app endBackgroundTask:self.playbackBackgroundTask]; 
} 
... 
@end 

Editar: Ah, y finally blogged about it.

+0

Funcionó como un encanto. ¡Eres un verdadero salvador! – Nailer

+0

Ah, broche de presión. No funcionó después de todo. Este no era mi problema en primer lugar, parece. – Nailer

+0

Gracias por el mensaje nevyn. Pero does not 'endBackgroundTask:' detener la tarea en segundo plano que acabamos de iniciar, por lo tanto, la aplicación no puede ejecutar ningún otro código de nuevo? es decir, después de llamar a 'endBackgroundTask:' la aplicación no podrá llamar a 'setPlaying:' de nuevo – Andrei