2012-07-18 9 views
8

Mam poprawnie włączone audio w tle dla mojej aplikacji (w plist). Odtwarzanie następnego utworu po zakończeniu bieżącej sesji przy użyciu SPPlaybackManager w tle (gdy telefon jest zablokowany/wyłączony) nie działa.Dźwięk w tle z cocoalibspotify

Po zakończeniu bieżącego utworu i zatrzymaniu dźwięku aplikacja nie rozpocznie odtwarzania następnego utworu, dopóki telefon nie zostanie odblokowany, a moja aplikacja ponownie się uruchomi.

Jak to naprawić? Oto fragment kodu, którego używam do rozpoczęcia odtwarzania następnego utworu. Obserwuję, że bieżący utwór staje się zerowy, a następnie rozpoczyna się odtwarzanie następnego utworu. Dziennik pokazuje mi, że następny bieżący utwór jest ustawiany w obiekcie menedżera odtwarzania, ale niestety jest cichy.

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

konsoli:

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

Odpowiedz

-2

CocoaLibSpotify robi dużo pracy, aby rozpocząć odtwarzanie utworu i prawdopodobnie będzie tarło nowych tematów wewnętrznych w procesie. Wątpię, by było to dozwolone w stylu audio w tle, więc prawdopodobnie będziesz musiał uruchomić tymczasowe zadanie w tle, aby zmienić ścieżki.

+0

Po prostu próbowałem umieścić 'beginBackgroundTaskWithExpirationHandler' bezpośrednio przed wywołaniem 'self.spotifyPlaybackManager playTrack: ...', a kod zawiesza się, gdy tylko próbuje się utworzyć nowe zadanie. Jakieś inne sugestie? – devinross

+0

Moja aplikacja audio (GroovePond) wykonuje wiele zadań w tle podczas odtwarzania dźwięku w tle, takich jak przyjmowanie nowych klientów i aktualizowanie stanu istniejących klientów, a firma Apple wydaje się nie mieć z tym żadnego problemu. Myślę, że ponieważ zadania są bezpośrednio związane z odtwarzaniem audio, są one dozwolone. – Dermot

8

Rozwiązanie jest bardzo proste, ale zrozumienie tego zajęło mi rok. Moim starym rozwiązaniem było uruchomienie zadania w tle tuż przed zakończeniem poprzedniego utworu i utrzymywanie go do momentu odtworzenia następnego utworu. To było bardzo podatne na błędy. Zamiast tego:

Śledź swój stan gry (odtwarzanie lub pauza). Po przejściu do gry uruchom zadanie w tle. Nigdy nie przestawaj, chyba że przejdziesz do Paused. Zachowaj stan jako odtwarzany nawet między ścieżkami. Tak długo, jak tryb audio w tle w pliku info.plist i audio jest odtwarzany, zadanie w tle będzie miało nieskończony czas oczekiwania.

Niektóre pseudokod:

@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 

Edit: Oh, a ja finally blogged about it.

+0

Pracował jak urok. Jesteś prawdziwym zbawicielem! – Nailer

+0

Ah, przystaw. W końcu nie działało. To nie był mój problem w pierwszej kolejności. – Nailer

+0

Dzięki za post nevyn. Ale czy "endBackgroundTask" nie zatrzymuje zadania tła, które właśnie uruchomiliśmy, dlatego aplikacja nie może ponownie uruchomić żadnego innego kodu? tj. po wywołaniu 'endBackgroundTask:' aplikacja nie będzie mogła wywołać 'setPlaying:' ponownie – Andrei