Answer the question
In order to leave comments, you need to log in
Scrubber slows down in AVPlayer?
Following the example from apple, I am making a player based on AVPlayer. ( AVPlayerDemo )
AVPlayer can play remote files, but if you turn on the video from the server and start rewinding the scrubber (UISlider), it starts to fail.
At the same time, everything rewinds smoothly in MPMoviePlayerViewController.
Are there any ideas how to fix this?
My test project code - https://github.com/nullproduction/Player
Rewind is implemented like this:
[scrubberSlider addTarget:self action:@selector(beginScrubbing:) forControlEvents:UIControlEventTouchDown];
[scrubberSlider addTarget:self action:@selector(endScrubbing:) forControlEvents:UIControlEventTouchUpInside];
[scrubberSlider addTarget:self action:@selector(endScrubbing:) forControlEvents:UIControlEventTouchUpOutside];
[scrubberSlider addTarget:self action:@selector(scrub:) forControlEvents:UIControlEventValueChanged];
- (void)initScrubberTimer
{
double interval = .1f;
CMTime playerDuration = [self playerItemDuration];
if (CMTIME_IS_INVALID(playerDuration))
{
return;
}
double duration = CMTimeGetSeconds(playerDuration);
if (isfinite(duration))
{
CGFloat width = CGRectGetWidth([scrubberSlider bounds]);
interval = 0.5f * duration / width;
}
__weak id weakSelf = self;
CMTime intervalSeconds = CMTimeMakeWithSeconds(interval, NSEC_PER_SEC);
mTimeObserver = [self.player addPeriodicTimeObserverForInterval:intervalSeconds
queue:dispatch_get_main_queue()
usingBlock:^(CMTime time) {
[weakSelf syncScrubber];
}];
}
- (void)syncScrubber
{
CMTime playerDuration = [self playerItemDuration];
if (CMTIME_IS_INVALID(playerDuration))
{
scrubberSlider.minimumValue = 0.0;
return;
}
double duration = CMTimeGetSeconds(playerDuration);
if (isfinite(duration))
{
float minValue = [scrubberSlider minimumValue];
float maxValue = [scrubberSlider maximumValue];
double time = CMTimeGetSeconds([self.player currentTime]);
[scrubberSlider setValue:(maxValue - minValue) * time / duration + minValue];
}
}
- (IBAction)beginScrubbing:(id)sender
{
mRestoreAfterScrubbingRate = [self.player rate];
[self.player setRate:0.f];
[self removePlayerTimeObserver];
}
- (IBAction)scrub:(id)sender
{
if ([sender isKindOfClass:[UISlider class]])
{
UISlider* slider = sender;
CMTime playerDuration = [self playerItemDuration];
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.player seekToTime:CMTimeMakeWithSeconds(time, NSEC_PER_SEC)];
}
}
}
- (IBAction)endScrubbing:(id)sender
{
if (!mTimeObserver)
{
CMTime playerDuration = [self playerItemDuration];
if (CMTIME_IS_INVALID(playerDuration))
{
return;
}
double duration = CMTimeGetSeconds(playerDuration);
if (isfinite(duration))
{
CGFloat width = CGRectGetWidth([scrubberSlider bounds]);
double tolerance = 0.5f * duration / width;
__weak id weakSelf = self;
CMTime intervalSeconds = CMTimeMakeWithSeconds(tolerance, NSEC_PER_SEC);
mTimeObserver = [self.player addPeriodicTimeObserverForInterval:intervalSeconds
queue:dispatch_get_main_queue()
usingBlock: ^(CMTime time) {
[weakSelf syncScrubber];
}];
}
}
if (mRestoreAfterScrubbingRate)
{
[self.player setRate:mRestoreAfterScrubbingRate];
mRestoreAfterScrubbingRate = 0.f;
}
}
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question