2016-02-16 1 views
3

Je suis en train de créer un lecteur vidéo avec AVPlayer.Videos charger à partir de YouTube. Je veux quand l'heure actuelle de la vidéo change, mon uiSlider et mon étiquette de temps peuvent mettre à jour. J'utilise la méthode "observerValueForKeyPath" pour attraper le statut "loadedTimeRanges" de l'élément joueur. Voici mon code:Swift observervalueforkeypath + loadedTimeRanges seulement appelé fois limité

override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) { 
     print("keyPath: \(keyPath)") 
     let playerItem:AVPlayerItem = object as! AVPlayerItem 
     if keyPath == "status" { 
      if playerItem.status == AVPlayerItemStatus.ReadyToPlay{ 
       print("AVPlayerItemStatusReadyToPlay") 
      } else if playerItem.status == AVPlayerItemStatus.Failed { 
       print("AVPlayerItemStatusFailed") 
      } 
     } else if keyPath == "loadedTimeRanges" { 
      let currentTime = playerItem.currentTime().seconds 
      let totalDuration = playerItem.duration.seconds 
      print("value: \(Float(currentTime/totalDuration))") 
      self.monitoringPlayback(player.currentItem!) 
      self.slider.setValue(Float(currentTime/totalDuration), animated: false) 
     } 
    } 

    func monitoringPlayback(playerItem:AVPlayerItem) { 
     let currentSecond:Double = playerItem.currentTime().seconds 
     self.updateVideoSlider(currentSecond) 
     let timeString = self.updateTime(playerItem.duration.seconds - currentSecond) 
     print("time string: \(timeString)") 
     self.lblTime.text = timeString 
    } 

Cependant, la méthode "observeValueForKeyPath" est seulement appelé à chaque fois 20-22. S'il vous plaît, vérifiez la capture d'écran du journal: https://gyazo.com/5ca57ba532689d83aea855ae41387f53 C'est la première fois que j'utilise cette méthode, alors peut-être que je n'ai pas compris comment cela fonctionne. Si quelqu'un le sait, dites-moi pourquoi. Merci d'avoir lu ma question.

+0

Si vous voulez connaître le courant temps de lecture pourquoi n'utilisez-vous pas la méthode 'currentTime' sur' AVPlayer'? . À l'heure actuelle, vous observez les plages de temps qui ont été chargées pour l'article. Une fois que vous n'avez plus de morceaux à charger, vous arrêtez d'obtenir la notification. –

+0

Mais comment puis-je connaître l'événement de changement d'heure? – Ashley

+0

A partir des docs 'Cette propriété n'est pas une valeur-clé observable; use addPeriodicTimeObserverForInterval: queue: usingBlock: ou addBoundaryTimeObserverForTimes: queue: usingBlock: à la place.' –

Répondre

-1

il, facile

var rightCurrentTimer: UILabel = {

let lbl = UILabel() 
    lbl.text = "00:00" 
    lbl.textColor = .white 
    lbl.translatesAutoresizingMaskIntoConstraints = false 
    lbl.font = UIFont.systemFont(ofSize: 11) 
    return lbl 

}() 

let leftWhatTimePlayed:UILabel = { 

    let lbl = UILabel() 
    lbl.translatesAutoresizingMaskIntoConstraints = false 
    lbl.textColor = .white 
    lbl.text = "00:00" 
    lbl.font = UIFont.systemFont(ofSize: 11) 
    return lbl 

}() 

let intervalle = CMTime (valeur: 1, échelle de temps: 1)

player?.addPeriodicTimeObserver(forInterval: interval, queue: DispatchQueue.main, using: { (timeProgress) in 

     let secondsPlay = CMTimeGetSeconds(timeProgress) 
     let secondString = String(format:"%02d" , Int(secondsPlay) % 60) 
     let minutesString = String(format:"%02d", Int(secondsPlay)/60) 

     self.leftWhatTimePlayed.text = "\(minutesString):\(secondString)" 

     if let duration = self.player?.currentItem?.duration { 

      let totalSecond = CMTimeGetSeconds(duration) 

      let whatSecondIsPlay = totalSecond - secondsPlay 

      let secondsIsPlay = String(format:"%02d" , Int(whatSecondIsPlay) % 60) 
      let minutesIsPlay = String(format: "%02d", Int(whatSecondIsPlay)/60) 

      self.rightCurrentTimer.text = "\(minutesIsPlay):\(secondsIsPlay)" 
      self.videoLengthTimeSlider.value = Float(secondsPlay/totalSecond) 

     } 


    })