I want to detect if my AVPlayer is buffering for the current location, so that I can show a loader or something. But I can't seem to find anything in the documentation for AVPlayer.
我想检测我的AVPlayer是否正在缓冲当前位置,以便我可以显示加载器或其他东西。但我似乎无法在AVPlayer的文档中找到任何内容。
4 个解决方案
#1
26
You can observe the values of your player.currentItem
:
您可以观察player.currentItem的值:
playerItem.addObserver(self, forKeyPath: "playbackBufferEmpty", options: .New, context: nil)
playerItem.addObserver(self, forKeyPath: "playbackLikelyToKeepUp", options: .New, context: nil)
playerItem.addObserver(self, forKeyPath: "playbackBufferFull", options: .New, context: nil)
then
override public func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
if object is AVPlayerItem {
switch keyPath {
case "playbackBufferEmpty":
// Show loader
case "playbackLikelyToKeepUp":
// Hide loader
case "playbackBufferFull":
// Hide loader
}
}
}
#2
13
The accepted answer didn't work for me, I used the code below to show the loader efficiently.
接受的答案对我不起作用,我使用下面的代码有效地显示装载机。
Swift 3
//properties
var observer:Any!
var player:AVPlayer!
self.observer = self.player.addPeriodicTimeObserver(forInterval: CMTimeMake(1, 600), queue: DispatchQueue.main) {
[weak self] time in
if self?.player.currentItem?.status == AVPlayerItemStatus.readyToPlay {
if let isPlaybackLikelyToKeepUp = self?.player.currentItem?.isPlaybackLikelyToKeepUp {
//do what ever you want with isPlaybackLikelyToKeepUp value, for example, show or hide a activity indicator.
}
}
}
#3
3
Swift 4 observations:
斯威夫特4观察:
var playerItem: AVPlayerItem?
var playbackLikelyToKeepUpKeyPathObserver: NSKeyValueObservation?
var playbackBufferEmptyObserver: NSKeyValueObservation?
var playbackBufferFullObserver: NSKeyValueObservation?
private func observeBuffering() {
let playbackBufferEmptyKeyPath = \AVPlayerItem.playbackBufferEmpty
playbackBufferEmptyObserver = playerItem?.observe(playbackBufferEmptyKeyPath, options: [.new]) { [weak self] (_, _) in
// show buffering
}
let playbackLikelyToKeepUpKeyPath = \AVPlayerItem.playbackLikelyToKeepUp
playbackLikelyToKeepUpKeyPathObserver = playerItem?.observe(playbackLikelyToKeepUpKeyPath, options: [.new]) { [weak self] (_, _) in
// hide buffering
}
let playbackBufferFullKeyPath = \AVPlayerItem.playbackBufferFull
playbackBufferFullObserver = playerItem?.observe(playbackBufferFullKeyPath, options: [.new]) { [weak self] (_, _) in
// hide buffering
}
}
Observers need to be removed after we are done observing.
观察完毕后,需要删除观察者。
To remove these three observers just set playbackBufferEmptyObserver
, playbackLikelyToKeepUpKeyPathObserver
and playbackBufferFullObserver
to nil
.
要删除这三个观察者,只需将playbackBufferEmptyObserver,playbackLikelyToKeepUpKeyPathObserver和playbackBufferFullObserver设置为nil即可。
No need to remove them manually (this is specific for observe<Value>(_ keyPath:, options:, changeHandler:)
method.
无需手动删除它们(这特定于观察
#4
1
#Updated in Swift 4 and worked fine
#Updated在Swift 4中工作正常
As through i have gone with accepted answer but didn't work in swift 4 for me so after certain research i have found this thinks from apple doc. There are two way to determine AVPlayer states that are,
由于我已经接受了接受的答案,但没有为我快速4工作,所以经过一定的研究,我发现这是从苹果医生认为。有两种方法可以确定AVPlayer状态,
- addPeriodicTimeObserverForInterval:queue:usingBlock: and
- addBoundaryTimeObserverForTimes:queue:usingBlock:
and using ways is like this
并使用方式是这样的
var observer:Any?
var avplayer : AVPlayer?
func preriodicTimeObsever(){
if let observer = self.observer{
//removing time obse
avplayer?.removeTimeObserver(observer)
observer = nil
}
let intervel : CMTime = CMTimeMake(1, 10)
observer = avplayer?.addPeriodicTimeObserver(forInterval: intervel, queue: DispatchQueue.main) { [weak self] time in
guard let strongSelf = self else {return}
let sliderValue : Float64 = CMTimeGetSeconds(time)
//this is the slider value update if you are using UISlider.
let playbackLikelyToKeepUp = strongSelf.avPlayer?.currentItem?.isPlaybackLikelyToKeepUp
if playbackLikelyToKeepUp == false{
//Here start the activity indicator inorder to show buffering
}else{
//stop the activity indicator
}
}
}
And Don't forget to kill time observer to save from memory leak. method for killing instance, add this method according to your need but i have used it in viewWillDisappear method.
并且不要忘记消磨时间观察者以避免内存泄漏。杀死实例的方法,根据需要添加此方法,但我在viewWillDisappear方法中使用了它。
if let observer = self.observer{
self.avPlayer?.removeTimeObserver(observer)
observer = nil
}
#1
26
You can observe the values of your player.currentItem
:
您可以观察player.currentItem的值:
playerItem.addObserver(self, forKeyPath: "playbackBufferEmpty", options: .New, context: nil)
playerItem.addObserver(self, forKeyPath: "playbackLikelyToKeepUp", options: .New, context: nil)
playerItem.addObserver(self, forKeyPath: "playbackBufferFull", options: .New, context: nil)
then
override public func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
if object is AVPlayerItem {
switch keyPath {
case "playbackBufferEmpty":
// Show loader
case "playbackLikelyToKeepUp":
// Hide loader
case "playbackBufferFull":
// Hide loader
}
}
}
#2
13
The accepted answer didn't work for me, I used the code below to show the loader efficiently.
接受的答案对我不起作用,我使用下面的代码有效地显示装载机。
Swift 3
//properties
var observer:Any!
var player:AVPlayer!
self.observer = self.player.addPeriodicTimeObserver(forInterval: CMTimeMake(1, 600), queue: DispatchQueue.main) {
[weak self] time in
if self?.player.currentItem?.status == AVPlayerItemStatus.readyToPlay {
if let isPlaybackLikelyToKeepUp = self?.player.currentItem?.isPlaybackLikelyToKeepUp {
//do what ever you want with isPlaybackLikelyToKeepUp value, for example, show or hide a activity indicator.
}
}
}
#3
3
Swift 4 observations:
斯威夫特4观察:
var playerItem: AVPlayerItem?
var playbackLikelyToKeepUpKeyPathObserver: NSKeyValueObservation?
var playbackBufferEmptyObserver: NSKeyValueObservation?
var playbackBufferFullObserver: NSKeyValueObservation?
private func observeBuffering() {
let playbackBufferEmptyKeyPath = \AVPlayerItem.playbackBufferEmpty
playbackBufferEmptyObserver = playerItem?.observe(playbackBufferEmptyKeyPath, options: [.new]) { [weak self] (_, _) in
// show buffering
}
let playbackLikelyToKeepUpKeyPath = \AVPlayerItem.playbackLikelyToKeepUp
playbackLikelyToKeepUpKeyPathObserver = playerItem?.observe(playbackLikelyToKeepUpKeyPath, options: [.new]) { [weak self] (_, _) in
// hide buffering
}
let playbackBufferFullKeyPath = \AVPlayerItem.playbackBufferFull
playbackBufferFullObserver = playerItem?.observe(playbackBufferFullKeyPath, options: [.new]) { [weak self] (_, _) in
// hide buffering
}
}
Observers need to be removed after we are done observing.
观察完毕后,需要删除观察者。
To remove these three observers just set playbackBufferEmptyObserver
, playbackLikelyToKeepUpKeyPathObserver
and playbackBufferFullObserver
to nil
.
要删除这三个观察者,只需将playbackBufferEmptyObserver,playbackLikelyToKeepUpKeyPathObserver和playbackBufferFullObserver设置为nil即可。
No need to remove them manually (this is specific for observe<Value>(_ keyPath:, options:, changeHandler:)
method.
无需手动删除它们(这特定于观察
#4
1
#Updated in Swift 4 and worked fine
#Updated在Swift 4中工作正常
As through i have gone with accepted answer but didn't work in swift 4 for me so after certain research i have found this thinks from apple doc. There are two way to determine AVPlayer states that are,
由于我已经接受了接受的答案,但没有为我快速4工作,所以经过一定的研究,我发现这是从苹果医生认为。有两种方法可以确定AVPlayer状态,
- addPeriodicTimeObserverForInterval:queue:usingBlock: and
- addBoundaryTimeObserverForTimes:queue:usingBlock:
and using ways is like this
并使用方式是这样的
var observer:Any?
var avplayer : AVPlayer?
func preriodicTimeObsever(){
if let observer = self.observer{
//removing time obse
avplayer?.removeTimeObserver(observer)
observer = nil
}
let intervel : CMTime = CMTimeMake(1, 10)
observer = avplayer?.addPeriodicTimeObserver(forInterval: intervel, queue: DispatchQueue.main) { [weak self] time in
guard let strongSelf = self else {return}
let sliderValue : Float64 = CMTimeGetSeconds(time)
//this is the slider value update if you are using UISlider.
let playbackLikelyToKeepUp = strongSelf.avPlayer?.currentItem?.isPlaybackLikelyToKeepUp
if playbackLikelyToKeepUp == false{
//Here start the activity indicator inorder to show buffering
}else{
//stop the activity indicator
}
}
}
And Don't forget to kill time observer to save from memory leak. method for killing instance, add this method according to your need but i have used it in viewWillDisappear method.
并且不要忘记消磨时间观察者以避免内存泄漏。杀死实例的方法,根据需要添加此方法,但我在viewWillDisappear方法中使用了它。
if let observer = self.observer{
self.avPlayer?.removeTimeObserver(observer)
observer = nil
}