AVPlayer
is fully customizable, unfortunately there are convenient methods in AVPlayer
for showing the time line progress bar.
AVPlayer *player = [AVPlayer playerWithURL:URL];
AVPlayerLayer *playerLayer = [[AVPlayerLayer playerLayerWithPlayer:avPlayer] retain];[self.view.layer addSubLayer:playerLayer];
I have an progress bar that indicates the how video has been played, and how much remained just as like MPMoviePlayer
.
So how to get the timeline of video from AVPlayer
and how to update the progress bar
Suggest me.
Please use the below code which is from apple example code "AVPlayerDemo".
double interval = .1f;
CMTime playerDuration = [self playerItemDuration]; // return player duration.
if (CMTIME_IS_INVALID(playerDuration))
{
return;
}
double duration = CMTimeGetSeconds(playerDuration);
if (isfinite(duration))
{
CGFloat width = CGRectGetWidth([yourSlider bounds]);
interval = 0.5f * duration / width;
}
/* Update the scrubber during normal playback. */
timeObserver = [[player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(interval, NSEC_PER_SEC)
queue:NULL
usingBlock:
^(CMTime time)
{
[self syncScrubber];
}] retain];
- (CMTime)playerItemDuration
{
AVPlayerItem *thePlayerItem = [player currentItem];
if (thePlayerItem.status == AVPlayerItemStatusReadyToPlay)
{
return([playerItem duration]);
}
return(kCMTimeInvalid);
}
And in syncScrubber method update the UISlider or UIProgressBar value.
- (void)syncScrubber
{
CMTime playerDuration = [self playerItemDuration];
if (CMTIME_IS_INVALID(playerDuration))
{
yourSlider.minimumValue = 0.0;
return;
}
double duration = CMTimeGetSeconds(playerDuration);
if (isfinite(duration) && (duration > 0))
{
float minValue = [ yourSlider minimumValue];
float maxValue = [ yourSlider maximumValue];
double time = CMTimeGetSeconds([player currentTime]);
[yourSlider setValue:(maxValue - minValue) * time / duration + minValue];
}
}
Thanks to iOSPawan for the code! I simplified the code to the necessary lines. This might be more clear to understand the concept. Basically I have implemented it like this and it works fine.
Before starting the video:
__weak NSObject *weakSelf = self;
[_player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(1.0 / 60.0, NSEC_PER_SEC)
queue:NULL
usingBlock:^(CMTime time){
[weakSelf updateProgressBar];
}];
[_player play];
Then you need to have a method to update your progress bar:
- (void)updateProgressBar
{
double duration = CMTimeGetSeconds(_playerItem.duration);
double time = CMTimeGetSeconds(_player.currentTime);
_progressView.progress = (CGFloat) (time / duration);
}
let progressView = UIProgressView(progressViewStyle: UIProgressViewStyle.Bar)
self.view.addSubview(progressView)
progressView.constrainHeight("\(1.0/UIScreen.mainScreen().scale)")
progressView.alignLeading("", trailing: "", toView: self.view)
progressView.alignBottomEdgeWithView(self.view, predicate: "")
player.addPeriodicTimeObserverForInterval(CMTimeMakeWithSeconds(1/30.0, Int32(NSEC_PER_SEC)), queue: nil) { time in
let duration = CMTimeGetSeconds(playerItem.duration)
progressView.progress = Float((CMTimeGetSeconds(time) / duration))
}
I know it's an old question, but someone may find it useful. It's only Swift version:
//set the timer, which will update your progress bar. You can use whatever time interval you want
private func setupProgressTimer() {
timer = Timer.scheduledTimer(withTimeInterval: 0.02, repeats: true, block: { [weak self] (completion) in
guard let self = self else { return }
self.updateProgress()
})
}
//update progression of video, based on it's own data
private func updateProgress() {
guard let duration = player?.currentItem?.duration.seconds,
let currentMoment = player?.currentItem?.currentTime().seconds else { return }
progressBar.progress = Float(currentMoment / duration)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With