【问题标题】:Swift observevalueforkeypath + loadedTimeRanges only called limited timesSwift observevalueforkeypath + loadedTimeRanges 只调用了有限的时间
【发布时间】:2016-05-28 01:53:21
【问题描述】:

我正在尝试使用从 youtube 加载的 AVPlayer.Videos 创建一个视频播放器。我想当视频当前时间改变时,我的 uiSlider 和我的时间标签可以更新。我正在使用“observeValueForKeyPath”方法从播放器项目中捕获“loadedTimeRanges”状态。这是我的代码:

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
    }

但是,“observeValueForKeyPath”方法每次只调用 20-22 次。请查看日志截图:https://gyazo.com/5ca57ba532689d83aea855ae41387f53 这是我第一次使用这种方法,所以我可能不明白它是如何工作的。如果有人知道,请告诉我为什么。感谢您阅读我的问题。

【问题讨论】:

  • 如果你想知道当前的播放时间,为什么不在AVPlayer 上使用currentTime 方法呢? .现在,您正在观察已为该项目加载的时间范围。一旦你用完了要加载的块,你就会停止收到通知。
  • 但是我怎么知道时间变化事件呢?
  • 来自文档This property is not key-value observable; use addPeriodicTimeObserverForInterval:queue:usingBlock: or addBoundaryTimeObserverForTimes:queue:usingBlock: instead.
  • 感谢您的出色解决方案。我使用 addPeriodicTimeObserverForInterval:queue:usingBlock: 并成功了。

标签: swift avplayer observers video-player


【解决方案1】:

很简单

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

}()

让interval = CMTime(value: 1, timescale: 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)

        }


    })

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-03
    • 2011-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多