在 AVPlayer 中播放网络不佳的流
Posted
技术标签:
【中文标题】在 AVPlayer 中播放网络不佳的流【英文标题】:Playing stream with bad internet in AVPlayer 【发布时间】:2014-04-02 13:48:49 【问题描述】:当 AVPlayer 播放来自网络流的资源时,它会在下载内容结束时暂停。
所以,我的问题是,如何知道它是因为网络不好而停止的?以及如何在下载后播放它,比如说,接下来的 10 秒资产?
【问题讨论】:
【参考方案1】:您可以在 AVPlayer 获得空缓冲区时添加观察者:
[[self.tracksPlayer currentItem] addObserver:self
forKeyPath:@"playbackBufferEmpty"
options:NSKeyValueObservingOptionNew
context:nil];
还有一个观察者,这样您就可以知道 AVPlayer 何时缓冲到足以跟上:
[[self.tracksPlayer currentItem] addObserver:self
forKeyPath:@"playbackLikelyToKeepUp"
options:NSKeyValueObservingOptionNew
context:nil];
然后在您的 KVO 回调中检查它:
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
if (object == [self.tracksPlayer currentItem] &&
[keyPath isEqualToString:@"playbackBufferEmpty"])
if ([self.tracksPlayer currentItem].playbackBufferEmpty)
NSLog(@"Buffer Empty");
else if (object == [self.tracksPlayer currentItem] &&
[keyPath isEqualToString:@"playbackLikelyToKeepUp"])
if ([self.tracksPlayer currentItem].playbackLikelyToKeepUp)
NSLog(@"LikelyToKeepUp");
【讨论】:
Apple 文档说playbackLikelyToKeepUp
可能是 NO
,即使 playbackBufferFull
是 YES
。据我了解,playbackLikelyToKeepUp
是基于互联网连接速度,而不是缓冲区中的数据量。
这其实是次要的,可以用也可以不用。虽然我不知道,但谢谢你的信息:)
所以我需要观察loadedTimeRanges
属性并检查它是否加载足够?
也可以观察status属性查看if (self.tracksplayer.status == AVPlayerStatusReadyToPlay)
【参考方案2】:
为了快速
1)
let playbackLikelyToKeepUpContext = UnsafeMutablePointer<(Void)>(nil)
or
let playbackLikelyToKeepUpContext = UnsafeMutablePointer<(Void)>()
2) //Add Observer
player.addObserver(self, forKeyPath: "currentItem.playbackLikelyToKeepUp",
options: NSKeyValueObservingOptions.New, context: playbackLikelyToKeepUpContext)
player.play()
3)
//Add observer
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>)
guard keyPath != nil else // a safety precaution
super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)
return
if (context == playbackLikelyToKeepUpContext)
if (player.currentItem!.playbackLikelyToKeepUp)
player.play()
Utilities.hideHUD(self.view)
else
Utilities.showHUD(self.view)
4) // Remove Observer
override func viewDidDisappear(animated: Bool)
player.removeObserver(self, forKeyPath: "currentItem.playbackLikelyToKeepUp")
【讨论】:
【参考方案3】:Swift 4 改变了 KVO 的方式。我们不是单独添加观察者和函数,而是在一个地方使用闭包(块)。
var observers: [NSKeyValueObservation]?
let playerItem = AVPlayerItem(url: YOUR_URL)
let emptyObserver = playerItem.observe(\.isPlaybackBufferEmpty)
[weak self] (object, observedChange) in
// show a progress bar
print("isPlaybackBufferEmpty")
let keepUpObserver = playerItem.observe(\.playbackLikelyToKeepUp)
[weak self] (object, observedChange) in
// hide progress bar and keep going
print("playbackLikelyToKeepUp")
self.observers = [emptyObserver, keepUpObserver]
【讨论】:
以上是关于在 AVPlayer 中播放网络不佳的流的主要内容,如果未能解决你的问题,请参考以下文章