在我的项目中,我使用Kolada视图(here)来展示一堆卡片,每张卡片上都有一个视频。有时当我加载下一个视频时,我的AVPlayer
无法播放视频,它只显示第一帧并被冻结。我正在使用几个观察者来跟踪视频实际播放的时间,如果它可能跟上播放的话。如果没有正确释放,观察者会导致播放冻结吗?如果没有,还有什么导致AVPlayer
的播放冻结?
更新:我注意到playbackLikelyToKeepUp
有时从未被调用过,当发生这种情况时,即使我更改了播放器项,AVPlayer
也不会再次调用它。因此视频播放永远不会恢复。
init(frame: CGRect, mediaURL: NSURL, thumbURL: NSURL?, isLoop: Bool) {
self.mediaURL = mediaURL
self.isLoop = isLoop
let asset = AVAsset(URL: mediaURL)
let item = AVPlayerItem(asset: asset)
player = AVPlayer(playerItem: item)
player!.actionAtItemEnd = .None
super.init(frame: frame)
asset.loadValuesAsynchronouslyForKeys(["duration"], completionHandler: { () -> Void in
var error: NSError?
let keyStatus: AVKeyValueStatus = asset.statusOfValueForKey("duration", error: &error)
switch (keyStatus) {
case .Loaded:
let duration: CMTime = asset.duration
self.currentDuration = duration
self.delegate?.updateDuration()
default:
break
}
})
NSNotificationCenter.defaultCenter().addObserver(
self,
selector: #selector(MediaPlayerView.playerItemDidReachEnd(_:)),
name: AVPlayerItemDidPlayToEndTimeNotification,
object: player!.currentItem)
self.timeObserver = self.player!.addPeriodicTimeObserverForInterval(CMTimeMakeWithSeconds(1.0 / 30.0, Int32(NSEC_PER_SEC)), queue: nil, usingBlock: {
[weak self] (time) -> Void in
if time.value > 0 {
self?.spinnerView?.stopAnimating()
if(self?.player != nil){
if(self?.player!.rate > 0){
self?.placeholderImageView?.hidden = true
}
}
let timeInSeconds = CMTimeGetSeconds(time)
self?.delegate?.playbackReachedTime(timeInSeconds)
}
})
player!.currentItem?.addObserver(self, forKeyPath: playbackLikelyToKeepUp, options: .New, context: &observationContext)
player!.addObserver(self, forKeyPath: "rate", options: .New, context: &observationContext)
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(MediaPlayerView.playerIsTapped(_:)))
addGestureRecognizer(tapGesture)
}
答案 0 :(得分:3)
在AVPlayer对象的现有实例上使用replaceCurrentItemWithPlayerItem,将值设置为nil以销毁它。