2016-11-08 13 views
0

我正在嘗試用AVPlayer剩餘時間更新UILabel。只要視頻開始,我就可以設置視頻當前剩餘時間的UILabel,但這個數字不隨視頻進度而改變。我搜查了蘋果的文檔,發現this block觀察視頻的時間,但是這個資源和其他關於Stackoverflow的問題並不一定指出如何使用這個函數更新UILabel。如何使用AVPlayer addperiodictimeobserverforinterval函數更新uilabel?

這裏是我的代碼,編譯,但我不能確定如何前進:

import UIKit 
import AVKit 
import AVFoundation 

extension UIView { 
    func fadeTransition(duration:CFTimeInterval) { 
     let animation:CATransition = CATransition() 
     animation.timingFunction = CAMediaTimingFunction(name: 
      kCAMediaTimingFunctionEaseInEaseOut) 
     animation.type = kCATransitionFade 
     animation.duration = duration 
     self.layer.add(animation, forKey: kCATransitionFade) 
    } 
} 

class MeetTheAuthorViewController: UIViewController { 




    @IBOutlet weak var videoTimeRemainingLabel: UILabel! 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     //playBackgroundMusic("bensound-jazzyfrenchy-castlesbackground.mp3") 
     // Do any additional setup after loading the view. 


    } 

    func btn_clicked(_ sender: UIBarButtonItem) { 
     // Do something 
    } 

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
     if segue.identifier == "videoSegue" 
     { 
      //set up the player 
      let videoURL = Bundle.main.url(forResource: "The Atlanta Goat_ Part One-HD", withExtension: "mp4") 
      let videoViewController = segue.destination as! AVPlayerViewController 
      videoViewController.player = AVPlayer(url: videoURL!) 
      videoViewController.player?.play() 

      //this code is an attempt to have a uilabel update with the time remaining in video 
      let videoDuration = CMTimeGetSeconds((videoViewController.player?.currentItem?.asset.duration)!) 
      let videoCurrentTime = videoViewController.player?.currentItem?.currentTime() 
      let timeRemainingInVideo = videoDuration - CMTimeGetSeconds(videoCurrentTime!) 

      videoTimeRemainingLabel.fadeTransition(duration: 0.4) 
      videoTimeRemainingLabel.text = String(describing: timeRemainingInVideo) 


      /*after the code above which updates the label initially, this code below is an attempt to update the UILabel over time as the video plays 
      */ 
      func addPeriodicTimeObserver() { 
       // Invoke callback every half second 
       let interval = CMTime(seconds: 0.5, 
             preferredTimescale: CMTimeScale(NSEC_PER_SEC)) 
       // Queue on which to invoke the callback 
       let mainQueue = DispatchQueue.main 
       // Add time observer 
       var timeObserverToken = 
        videoViewController.player?.addPeriodicTimeObserver(forInterval: interval, queue: mainQueue) { 
         [weak self] time in 
         // update player transport UI 
       } 
      } 
      //end of attempt to update time remaining label 

      NotificationCenter.default.addObserver(self, selector: #selector(MeetTheAuthorViewController.playerDidFinishPlaying), 
                  name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: videoViewController.player?.currentItem) 



     } 
    } 

    func playerDidFinishPlaying() { 
     print("Video Finished") 
     self.dismiss(animated: true, completion: nil) 
    } 



} 

回答

1

如果你有意見// update player transport UI,你需要重新計算timeRemainingInVideo和更新標籤。

+0

許多讚賞@Jerry但是當我更新的代碼讓timeRemainingInVideo = videoDuration - CMTimeGetSeconds(間隔) 自.videoTimeRemainingLabel.text =字符串(描述? timeRemainingInVideo) 這不會更改UILabel。 –

+1

如果你設置了一個斷點,它會不會觸及?那裏有效嗎?你可以用別的東西來設置標籤嗎? – Jerry

+0

yes self是必需的,因爲Xcode說我無法從閉包中引用它,並且在將UILable設置爲「閉包打開」時,它不會按預期更新。 –

0

更新UI應該是在主線程

videoViewController.player?.addPeriodicTimeObserver(forInterval: interval, queue: nil, using: { (time) in 
     let currentTime = floor(CMTimeGetSeconds(time)) 
     print(currentTime) 
     // update UI should be in main thread 
     DispatchQueue.main.async { 
      videoTimeRemainingLabel.text = String(currentTime) 
     } 
    })