背景音频与cocoalibspotify

问题描述:

我已经适当地为我的应用程序(在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 

CocoaLibSpotify做了很多的工作,开始播放曲目,并在这个过程中可能会产生新的内螺纹。我怀疑这是允许在背景的音频风格,所以你可能需要开始一个临时的后台任务来改变曲目。

+0

我刚刚尝试在调用'self.spotifyPlaybackManager playTrack:...'前直接放入'beginBackgroundTaskWithExpirationHandler',代码在尝试创建新任务时立即暂停运行。还有其他建议吗? – devinross 2012-07-18 08:32:00

+0

我的音频应用程序(GroovePond)在播放背景音频时会执行很多后台任务,例如接受新客户端和更新现有客户端的状态,并且Apple似乎没有任何问题。我认为,因为这些任务与音频的回放直接相关,所以它们是允许的。 – Dermot 2013-02-22 02:38:36

该解决方案非常简单,但花了我一年时间才意识到它。我以前的解决方案是在上一首歌曲结束之前开始后台任务,并保持播放直到下一首歌曲正在播放。这是非常容易出错的。相反:

跟踪您的播放状态(播放或暂停)。每当你转换到播放,开始一个后台任务。永远不要停止它,除非你转换成已暂停。即使在音轨之间也保持播放状态。只要你的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