Barra de progreso de la línea de time para AVPlayer

AVPlayer es completamente personalizable, lamentablemente hay methods convenientes en AVPlayer para mostrar la barra de progreso de la línea de time.

 AVPlayer *player = [AVPlayer playerWithURL:URL]; AVPlayerLayer *playerLayer = [[AVPlayerLayer playerLayerWithPlayer:avPlayer] retain];[self.view.layer addSubLayer:playerLayer]; 

Tengo una barra de progreso que indica cómo se ha reproducido el video, y cuánto se mantuvo igual que MPMoviePlayer .

Entonces, ¿cómo get la línea de time del video de AVPlayer y cómo actualizar la barra de progreso

Sugiereme.

Utilice el código siguiente que figura en el código de ejemplo de Apple "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); } 

Y en el método syncScrubber, actualice el valor UISlider o UIProgressBar.

 - (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]; } } 

¡Gracias a iOSPawan por el código! Simplificé el código a las líneas necesarias. Esto podría ser más claro para comprender el concepto. Básicamente lo he implementado así y funciona bien.

Antes de comenzar el video:

 __weak NSObject *weakSelf = self; [_player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(1.0 / 60.0, NSEC_PER_SEC) queue:NULL usingBlock:^(CMTime time){ [weakSelf updateProgressBar]; }]; [_player play]; 

Entonces necesitas tener un método para actualizar tu barra de progreso:

 - (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, pnetworkingicate: "") 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)) } 

para la línea de time hago esto

 -(void)changeSliderValue { double duration = CMTimeGetSeconds(self.player.currentItem.duration); [lengthSlider setMaximumValue:(float)duration]; lengthSlider.value = CMTimeGetSeconds([self.player currentTime]); int seconds = lengthSlider.value,minutes = seconds/60,hours = minutes/60; int secondsRemain = lengthSlider.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]; timePlayed.text = [NSString stringWithFormat:@"%@:%@:%@",hourStr,minuteStr,secondStr]; timeRemain.text = [NSString stringWithFormat:@"-%@:%@:%@",hourStrRemain,minuteStrRemain,secondStrRemain]; 

E import del marco CoreMedia

lengthSlider es UISlider

En mi caso, el siguiente código funciona Swift 3:

 var timeObserver: Any? override func viewDidLoad() { ........ let interval = CMTime(seconds: 0.05, prefernetworkingTimescale: CMTimeScale(NSEC_PER_SEC)) timeObserver = avPlayer.addPeriodicTimeObserver(forInterval: interval, queue: DispatchQueue.main, using: { elapsedTime in self.updateSlider(elapsedTime: elapsedTime) }) } func updateSlider(elapsedTime: CMTime) { let playerDuration = playerItemDuration() if CMTIME_IS_INVALID(playerDuration) { seekSlider.minimumValue = 0.0 return } let duration = Float(CMTimeGetSeconds(playerDuration)) if duration.isFinite && duration > 0 { seekSlider.minimumValue = 0.0 seekSlider.maximumValue = duration let time = Float(CMTimeGetSeconds(elapsedTime)) seekSlider.setValue(time, animated: true) } } private func playerItemDuration() -> CMTime { let thePlayerItem = avPlayer.currentItem if thePlayerItem?.status == .readyToPlay { return thePlayerItem!.duration } return kCMTimeInvalid } override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) avPlayer.removeTimeObserver(timeObserver!) }