AVPlayer causa un locking mientras se actualiza el control deslizante de progreso con Fallo de aserción en –

Estoy recibiendo el error dentro de la aplicación

" Assertion failure in -[AVPlayerPeriodicCaller initWithPlayer:interval:queue:block:], /SourceCache/EmbeddedAVFoundation/EmbeddedAVFoundation-461.12/Fig/AVPlayer.m:3993 Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: CMTIME_COMPARE_INLINE(interval, >, kCMTimeZero)' 

¿Alguna idea de por qué esto puede estar sucediendo?

Estoy limitado a utilizar AvPlayer solo porque necesito transmitir files de gran tamaño. Avidioplayer no es una opción. Entonces, también implementé un control deslizante de scrubber. Mi implementación de AVplayer es la siguiente:

 -(void)playAudioForFile:(NSString *)fileName{ [self.suraPlayer removeTimeObserver:playbackObserver]; [self.suraPlayer removeTimeObserver:mTimeObserver]; self.suraPlayer = nil; NSURL* url = [self getURLStringForFileName:fileName]; AVPlayer *player = [[AVPlayer alloc]initWithURL:url]; self.suraPlayer = player; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerItemDidReachEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:[suraPlayer currentItem]]; [self.suraPlayer play]; [self.suraPlayer addObserver:self forKeyPath:@"status" options:0 context:nil]; [self initScrubberTimer]; [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(updateProgress) userInfo:nil repeats:YES]; //[self metadataForAsset:self.suraPlayer.currentItem.asset]; 

}

 -(void)updateProgress { // NSLog(@"self.mScrubber.value %f", self.mScrubber.value); 

// ESTA ES LA LÍNEA DONDE EL DEBUGADOR CUMPLE CON ALGÚN TIEMPO

 float duration = CMTimeGetSeconds(self.suraPlayer.currentItem.duration); if (self.suraPlayer.currentItem.status==AVPlayerStatusReadyToPlay ) [self.mScrubber setMaximumValue:duration]; self.mScrubber.value = CMTimeGetSeconds(self.suraPlayer.currentTime); int seconds = self.mScrubber.value, minutes = seconds/60,hours = minutes/60; int secondsRemain = self.mScrubber.maximumValue - seconds,minutesRemain = secondsRemain/60,hoursRemain = minutesRemain/60; seconds = seconds-minutes*60; minutes = minutes-hours*60; secondsRemain = secondsRemain - minutesRemain*60; minutesRemain = minutesRemain - hoursRemain*60; NSString *hourStr,*minuteStr,*secondStr,*hourStrRemain,*minuteStrRemain,*secondStrRemain; hourStr = hours > 9 ? [NSString stringWithFormat:@"%d",hours] : [NSString stringWithFormat:@"0%d",hours]; minuteStr = minutes > 9 ? [NSString stringWithFormat:@"%d",minutes] : [NSString stringWithFormat:@"0%d",minutes]; secondStr = seconds > 9 ? [NSString stringWithFormat:@"%d",seconds] : [NSString stringWithFormat:@"0%d",seconds]; hourStrRemain = hoursRemain > 9 ? [NSString stringWithFormat:@"%d",hoursRemain] : [NSString stringWithFormat:@"0%d",hoursRemain]; minuteStrRemain = minutesRemain > 9 ? [NSString stringWithFormat:@"%d",minutesRemain] : [NSString stringWithFormat:@"0%d",minutesRemain]; secondStrRemain = secondsRemain > 9 ? [NSString stringWithFormat:@"%d",secondsRemain] : [NSString stringWithFormat:@"0%d",secondsRemain]; self.timePlayerLabel.text = [NSString stringWithFormat:@"%@:%@:%@",hourStr,minuteStr,secondStr]; self.timeRemainingLabel.text = [NSString stringWithFormat:@"-%@:%@:%@",hourStrRemain,minuteStrRemain,secondStrRemain]; } -(void)initScrubberTimer { double interval = .1f; CMTime playerDuration = self.suraPlayer.currentItem.duration; if (CMTIME_IS_INVALID(playerDuration)) { return; } double duration = CMTimeGetSeconds(playerDuration); if (isfinite(duration)) { CGFloat width = CGRectGetWidth([self.mScrubber bounds]); interval = 0.5f * duration / width; } /* Update the scrubber during normal playback. */ mTimeObserver = [self.suraPlayer addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(interval, NSEC_PER_SEC) queue:NULL /* If you pass NULL, the main queue is used. */ usingBlock:^(CMTime time) { }]; [self syncScrubber]; } /* Set the scrubber based on the player current time. */ - (void)syncScrubber { CMTime playerDuration = self.suraPlayer.currentItem.duration; if (CMTIME_IS_INVALID(playerDuration)) { self.mScrubber.minimumValue = 0.0; return; } double duration = CMTimeGetSeconds(playerDuration); if (isfinite(duration)) { float minValue = [self.mScrubber minimumValue]; float maxValue = [self.mScrubber maximumValue]; double time = CMTimeGetSeconds([self.suraPlayer currentTime]); [self.mScrubber setValue:(maxValue - minValue) * time / duration + minValue]; } } /* The user is dragging the movie controller thumb to scrub through the movie. */ /* Set the player current time to match the scrubber position. */ - (IBAction)scrub:(id)sender { if ([sender isKindOfClass:[UISlider class]]) { UISlider* slider = sender; CMTime playerDuration = self.suraPlayer.currentItem.duration; if (CMTIME_IS_INVALID(playerDuration)) { return; } double duration = CMTimeGetSeconds(playerDuration); if (isfinite(duration)) { float minValue = [slider minimumValue]; float maxValue = [slider maximumValue]; float value = [slider value]; double time = duration * (value - minValue) / (maxValue - minValue); [self.suraPlayer seekToTime:CMTimeMakeWithSeconds(time, NSEC_PER_SEC)]; } } } - (IBAction)beginScrubbing:(id)sender { mRestoreAfterScrubbingRate = [self.suraPlayer rate]; [self.suraPlayer setRate:0.f]; /* Remove previous timer. */ [self removePlayerTimeObserver]; } /* The user has released the movie thumb control to stop scrubbing through the movie. */ - (IBAction)endScrubbing:(id)sender { __weak typeof(self) weakSelf = self; if (!mTimeObserver) { CMTime playerDuration = self.suraPlayer.currentItem.duration; if (CMTIME_IS_INVALID(playerDuration)) { return; } double duration = CMTimeGetSeconds(playerDuration); if (isfinite(duration)) { CGFloat width = CGRectGetWidth([self.mScrubber bounds]); double tolerance = 0.5f * duration / width; mTimeObserver = [self.suraPlayer addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(tolerance, NSEC_PER_SEC) queue:NULL usingBlock: ^(CMTime time) { [weakSelf syncScrubber]; }]; } } if (mRestoreAfterScrubbingRate) { [self.suraPlayer setRate:mRestoreAfterScrubbingRate]; mRestoreAfterScrubbingRate = 0.f; } } - (BOOL)isScrubbing { return mRestoreAfterScrubbingRate != 0.f; } -(void)enableScrubber { self.mScrubber.enabled = YES; } -(void)disableScrubber { self.mScrubber.enabled = NO; } -(void)removePlayerTimeObserver { if (mTimeObserver) { [self.suraPlayer removeTimeObserver:mTimeObserver]; mTimeObserver = nil; } } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (object == suraPlayer && [keyPath isEqualToString:@"status"]) { if (suraPlayer.status == AVPlayerStatusFailed) { NSLog(@"AVPlayer Failed"); } else if (suraPlayer.status == AVPlayerStatusReadyToPlay) { NSLog(@"AVPlayerStatusReadyToPlay"); // NSLog(@"Common MetaData %@", self.suraPlayer.currentItem.asset.commonMetadata); AVAsset * asset = self.suraPlayer.currentItem.asset; [self metadataForAsset:asset]; } else if (suraPlayer.status == AVPlayerItemStatusUnknown) { NSLog(@"AVPlayer Unknown"); } } } - (NSString *)titleForAsset:(AVAsset *)asset{ NSArray *titles = [AVMetadataItem metadataItemsFromArray:asset.commonMetadata withKey:AVMetadataCommonKeyTitle keySpace:AVMetadataKeySpaceCommon]; AVMetadataItem *title; NSString * currentTitle; if(titles.count>0) { title= [titles objectAtIndex:0]; currentTitle= [title.value copyWithZone:nil]; } if (self.suraPlayer.currentItem.asset != asset) asset = nil; return currentTitle; } - (void)metadataForAsset:(AVAsset *)asset{ self.artWorkImage.image = [UIImage imageNamed:@"Colorful-Burst-iPad-wallpaper-ilikewallpaper_com.jpg"]; NSArray *titles = [AVMetadataItem metadataItemsFromArray:asset.commonMetadata withKey:AVMetadataCommonKeyTitle keySpace:AVMetadataKeySpaceCommon]; NSArray *artists = [AVMetadataItem metadataItemsFromArray:asset.commonMetadata withKey:AVMetadataCommonKeyArtist keySpace:AVMetadataKeySpaceCommon]; NSArray *albumNames = [AVMetadataItem metadataItemsFromArray:asset.commonMetadata withKey:AVMetadataCommonKeyAlbumName keySpace:AVMetadataKeySpaceCommon]; AVMetadataItem *artist; AVMetadataItem *title; AVMetadataItem *albumName; NSString * currentTitle; NSString * currentArtist; NSString * currentAlbumName; if(titles.count>0) { title= [titles objectAtIndex:0]; currentTitle= [title.value copyWithZone:nil]; self.audioTitle.text = currentTitle; } if(artists.count>0) { artist= [artists objectAtIndex:0]; currentArtist = [artist.value copyWithZone:nil]; } if (albumNames.count>0){ albumName= [albumNames objectAtIndex:0]; currentAlbumName = [albumName.value copyWithZone:nil]; } NSArray *keys = [NSArray arrayWithObjects:@"commonMetadata", nil]; [asset loadValuesAsynchronouslyForKeys:keys completionHandler:^{ NSArray *artworks = [AVMetadataItem metadataItemsFromArray:asset.commonMetadata withKey:AVMetadataCommonKeyArtwork keySpace:AVMetadataKeySpaceCommon]; for (AVMetadataItem *item in artworks) { if ([item.keySpace isEqualToString:AVMetadataKeySpaceID3]) { NSDictionary *d = [item.value copyWithZone:nil]; self.artWorkImage.image = [UIImage imageWithData:[d objectForKey:@"data"]]; } else if ([item.keySpace isEqualToString:AVMetadataKeySpaceiTunes]) { self.artWorkImage.image = [UIImage imageWithData:[item.value copyWithZone:nil]]; } } }]; } - (void)playerItemDidReachEnd:(NSNotification *)notification { // code here to play next sound file if (indexOfSelectedItem<self.filtenetworkingAudiosArray.count){ indexOfSelectedItem = indexOfSelectedItem+1; [self playAudioForFile:[self.filtenetworkingAudiosArray objectAtIndex:indexOfSelectedItem]]; [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:indexOfSelectedItem inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES]; } } - (IBAction)sliderValueChangedForDuration:(id)sender { if ([sender isKindOfClass:[UISlider class]]) { UISlider* slider = sender; CMTime playerDuration = self.suraPlayer.currentItem.duration; if (CMTIME_IS_INVALID(playerDuration)) { return; } double duration = CMTimeGetSeconds(playerDuration); if (isfinite(duration)) { float minValue = [slider minimumValue]; float maxValue = [slider maximumValue]; float value = [slider value]; double time = duration * (value - minValue) / (maxValue - minValue); [self.suraPlayer seekToTime:CMTimeMakeWithSeconds(time, NSEC_PER_SEC)]; } } } 

Tarde al juego, pero en caso de que alguien más se tope con esto, tuve este problema debido a la forma en que estaba estableciendo el intervalo de time para el observador periódico.

Cambiar a:

 CMTime interval = CMTimeMake(33, 1000); 

Las cosas hechas funcionan para mí.