2012-07-18 94 views
8

我已經適當地爲我的應用程序(在plist)啓用背景音頻。在後臺使用SPPlaybackManager完成當前電話後(當電話被鎖定/關閉時)播放下一首曲目不起作用。背景音頻與cocoalibspotify

噹噹前曲目結束並且音頻停止時,應用程序將不會開始播放下一首曲目,直到手機解鎖並且我的應用程序再次變爲活動狀態。

我該如何解決這個問題?以下是我用來開始播放下一首歌曲的一段代碼。我觀察到當前曲目變爲零,然後開始播放下一首曲目。日誌顯示我下一個當前曲目正在播放管理器對象中設置,但它唉聲匿跡。

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

控制檯:

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

回答

-2

CocoaLibSpotify做了很多的工作,開始播放曲目,並在這個過程中可能會產生新的內螺紋。我懷疑這是允許在背景的音頻風格,所以你可能需要開始一個臨時的後臺任務來改變曲目。

+0

我剛剛嘗試在調用'self.spotifyPlaybackManager playTrack:...'前直接放入'beginBackgroundTaskWithExpirationHandler',代碼在嘗試創建新任務時立即暫停運行。還有其他建議嗎? – devinross 2012-07-18 08:32:00

+0

我的音頻應用程序(GroovePond)在播放背景音頻時會執行很多後臺任務,例如接受新客戶端和更新現有客戶端的狀態,並且Apple似乎沒有任何問題。我認爲,因爲這些任務與音頻的回放直接相關,所以它們是允許的。 – Dermot 2013-02-22 02:38:36

8

該解決方案非常簡單,但花了我一年時間才意識到它。我以前的解決方案是在上一首歌曲結束之前開始後臺任務,並保持播放直到下一首歌曲正在播放。這是非常容易出錯的。相反:

跟蹤您的播放狀態(播放或暫停)。每當你轉換到播放,開始一個後臺任務。永遠不要停止它,除非你轉換成已暫停。即使在音軌之間也保持播放狀態。只要你的info.plist中有音頻背景模式並且音頻正在播放,你的後臺任務就會有無限的超時。

一些僞代碼:

@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 

編輯:哦,我finally blogged about it

+0

工作就像一個魅力。你是一個真正的救星! – Nailer 2013-06-12 15:16:40

+0

啊,快點。畢竟沒有工作。這似乎不是我的第一個問題。 – Nailer 2013-06-12 17:05:45

+0

感謝您的帖子nevyn。但不'endBackgroundTask:'停止我們剛剛開始的後臺任務,因此應用程序不能再運行任何其他代碼?即在調用'endBackgroundTask:'後,應用程序將不能再次調用'setPlaying:' – Andrei 2013-08-28 20:57:33