我正在使用AVPlayer构建一个应用程序,它将播放来自api的歌曲。
当歌曲结束时,将播放下一首歌曲。为此,我使用以下代码:
- (void)viewDidLoad
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playbackFinished:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[_audioPlayer currentItem]];
}
-(void)playbackFinished:(NSNotification *)notification {
// flagSkip = NO;
NSLog(@"## %@ ", NSStringFromSelector(_cmd));
// if(flagSkip == NO)
[[DataSingleton sharedMySingleton] nextTrack];
// else
// flagSkip = NO;
}
在滑动手势上,将播放下一首歌曲。 为此,我删除通知观察者并再次添加它,如下所示:
- (IBAction)skipButtonPressed:(id)sender
{
[[DataSingleton sharedMySingleton] nextTrack];
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:[_audioPlayer currentItem]];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playbackFinished:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[_audioPlayer currentItem]];
}else{
//
}
}
但是当我滑动时,有时会调用通知方法。
我哪里出错了?我该如何解决这个问题?
编辑以包含[[DataSingleton sharedMySingleton] nextTrack]
-(void)nextTrack{
NSDictionary *prevTrackInfo;
if (currentIndex == -1){
// We're at the start of a refilled list, so previousTrack should be
// the only thing in the cache dir. Clean it up.
dispatch_queue_t removeFilesQueue;
NSLog(@"## %@ removeFilesQueue", NSStringFromSelector(_cmd));
removeFilesQueue = dispatch_queue_create("com.zombieprocess.removeFilesQueue", DISPATCH_QUEUE_SERIAL);
dispatch_sync(removeFilesQueue, ^{
// Code goes here
NSError *error = nil;
[fileMgr removeItemAtPath:[self getFeedBandsCacheDir] error:&error];
[fileMgr createDirectoryAtPath:[self getFeedBandsCacheDir] withIntermediateDirectories:YES attributes:nil error:nil];
});
//dispatch_release(removeFilesQueue);
} else{
if (trackInfo){
prevTrackInfo = trackInfo;
}else{
NSLog(@"nextTrack, attempting to store prevTrackInfo, no trackInfo for currentIndex: %d", currentIndex);
}
}
currentIndex += 1;
// We should not have this, but just in case
if (currentIndex >= self.feedEntries.count) {
// We are at the end. Get the feed again.
NSLog(@"## %@ currentIndex >= self.feedEntries.count", NSStringFromSelector(_cmd));
if (self.feedEntries.count == 0) {
[self loadFeed];
return;
}
currentIndex = 0; // This will loop it back to the beginning
// [self loadFeed];
// return;
}
trackInfo = [self.feedEntries objectAtIndex:currentIndex];
[self dispatchPlayNotification];
if (prevTrackInfo && [self isTrackCached:prevTrackInfo] && prevTrackInfo != trackInfo && feedEntries.count > [self numberOfSongsToCache]){
NSLog(@"nextTrack, deleting cached copy: %@", [[prevTrackInfo objectForKey:@"file_url"] lastPathComponent]);
[self deleteCachedTrack:prevTrackInfo completionBlock:^{
[self fillDownloadQueue];
}];
} else {
[self fillDownloadQueue];
}
}
答案 0 :(得分:0)
我猜你已经换了下一首歌。因此,您无法使用[_audioPlayer currentItem]
删除通知观察者,因为它已经更改。
更新1。
尝试替换第1行和第2行:
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:[_audioPlayer currentItem]];
[[DataSingleton sharedMySingleton] nextTrack];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:[_audioPlayer currentItem]];
答案 1 :(得分:-1)
我会在方法(void)playbackFinished:(NSNotification *)notification
中读取播放器上的当前状态,而不是删除通知侦听器。
例如:
- (IBAction)skipButtonPressed:(id)sender
{
didSkipSong = YES;
[[DataSingleton sharedMySingleton] nextTrack];
}
并在-(void)playbackFinished:(NSNotification *)notification
-(void)playbackFinished:(NSNotification *)notification {
if(didSkipSong){
didSkipSong = NO;
return;
}
[[DataSingleton sharedMySingleton] nextTrack];
}