vrw*_*wim 27 buffering ios avplayer
我想检测我的AVPlayer是否正在缓冲当前位置,以便我可以显示加载器或其他东西.但我似乎无法在AVPlayer的文档中找到任何内容.
Mar*_*ssa 40
你可以观察你的价值观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)
Run Code Online (Sandbox Code Playgroud)
然后
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
}
}
}
Run Code Online (Sandbox Code Playgroud)
ayt*_*tek 17
接受的答案对我不起作用,我使用下面的代码有效地显示加载程序.
斯威夫特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.
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 7
对我来说,上面接受的答案没有用,但是这种方法可以用。您可以使用timeControlStatus,但它仅在iOS 10以上可用。
根据苹果官方文件
一种状态,指示在等待适当的网络条件时是当前正在进行播放,无限期暂停还是暂停播放
将此观察者添加到播放器。
player.addObserver(self, forKeyPath: “timeControlStatus”, options: [.old, .new], context: nil)
Run Code Online (Sandbox Code Playgroud)
然后,观察
func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?)
Run Code Online (Sandbox Code Playgroud)
在上面的方法中使用下面的代码
override public func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "timeControlStatus", let change = change, let newValue = change[NSKeyValueChangeKey.newKey] as? Int, let oldValue = change[NSKeyValueChangeKey.oldKey] as? Int {
let oldStatus = AVPlayer.TimeControlStatus(rawValue: oldValue)
let newStatus = AVPlayer.TimeControlStatus(rawValue: newValue)
if newStatus != oldStatus {
DispatchQueue.main.async {[weak self] in
if newStatus == .playing || newStatus == .paused {
self?.loaderView.isHidden = true
} else {
self?.loaderView.isHidden = false
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这已在上面的iOS 11上使用swift 4进行了测试,并且正在运行。
在斯威夫特 5.3 中
变量:
private var playerItemBufferEmptyObserver: NSKeyValueObservation?
private var playerItemBufferKeepUpObserver: NSKeyValueObservation?
private var playerItemBufferFullObserver: NSKeyValueObservation?
Run Code Online (Sandbox Code Playgroud)
添加观察者
playerItemBufferEmptyObserver = player.currentItem?.observe(\AVPlayerItem.isPlaybackBufferEmpty, options: [.new]) { [weak self] (_, _) in
guard let self = self else { return }
self.showLoadingIndicator(over: self)
}
playerItemBufferKeepUpObserver = player.currentItem?.observe(\AVPlayerItem.isPlaybackLikelyToKeepUp, options: [.new]) { [weak self] (_, _) in
guard let self = self else { return }
self.dismissLoadingIndicator()
}
playerItemBufferFullObserver = player.currentItem?.observe(\AVPlayerItem.isPlaybackBufferFull, options: [.new]) { [weak self] (_, _) in
guard let self = self else { return }
self.dismissLoadingIndicator()
}
Run Code Online (Sandbox Code Playgroud)
删除观察者
playerItemBufferEmptyObserver?.invalidate()
playerItemBufferEmptyObserver = nil
playerItemBufferKeepUpObserver?.invalidate()
playerItemBufferKeepUpObserver = nil
playerItemBufferFullObserver?.invalidate()
playerItemBufferFullObserver = nil
Run Code Online (Sandbox Code Playgroud)
Swift 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
}
}
Run Code Online (Sandbox Code Playgroud)
完成观察后需要移除观察者。
删除这三个观察者刚刚设置playbackBufferEmptyObserver
,playbackLikelyToKeepUpKeyPathObserver
并playbackBufferFullObserver
为nil
。
无需手动删除它们(这是特定于observe<Value>(_ keyPath:, options:, changeHandler:)
方法的。
#已在Swift 4中更新并正常运行
由于我已经接受了可接受的答案,但对我而言却没有迅速完成工作,因此在进行某些研究后,我发现这是苹果医生的想法。确定AVPlayer状态的方法有两种:
和使用方式是这样的
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 `self` = self else { return }
let sliderValue : Float64 = CMTimeGetSeconds(time)
//this is the slider value update if you are using UISlider.
let playbackLikelyToKeepUp = self.avPlayer?.currentItem?.isPlaybackLikelyToKeepUp
if playbackLikelyToKeepUp == false{
//Here start the activity indicator inorder to show buffering
}else{
//stop the activity indicator
}
}
}
Run Code Online (Sandbox Code Playgroud)
并且不要忘记杀死时间观察者以避免内存泄漏。杀死实例的方法,根据您的需要添加此方法,但是我在viewWillDisappear方法中使用了它。
if let observer = self.observer{
self.avPlayer?.removeTimeObserver(observer)
observer = nil
}
Run Code Online (Sandbox Code Playgroud)
小智 5
更新为 Swift 4.2
var player : AVPlayer? = nil
let videoUrl = URL(string: "https://wolverine.raywenderlich.com/content/ios/tutorials/video_streaming/foxVillage.mp4")
self.player = AVPlayer(url: videoUrl!)
self.player?.addPeriodicTimeObserver(forInterval: CMTimeMake(value: 1, timescale: 600), queue: DispatchQueue.main, using: { time in
if self.player?.currentItem?.status == AVPlayerItem.Status.readyToPlay {
if let isPlaybackLikelyToKeepUp = self.player?.currentItem?.isPlaybackLikelyToKeepUp {
//do what ever you want with isPlaybackLikelyToKeepUp value, for example, show or hide a activity indicator.
//MBProgressHUD.hide(for: self.view, animated: true)
}
}
})
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
18546 次 |
最近记录: |