我使用AVPlayer传输音频。它运作良好。但是现在我需要制作一个滑块来向前和向后移动音频,就像典型的音乐播放器一样。我使用了函数seekToTime
,它与本地音频文件配合得很好。但是当我从网址流传输歌曲时,当我转发大范围的滑块时,该功能会停止音频。
我的猜测是正在下载歌曲,如果我向前移动大范围的滑块,那么可能是系统没有下载当时的歌曲数据包,所以它会暂停播放器。
让我们说我只是点击一个按钮来播放歌曲,但现在我立即在0到100秒移动滑块。在这种情况下,系统无法正常工作并停止播放器。由于当时缺少数据包。
有谁知道如何克服这个问题,还是有任何其他方法。我正在使用SWIFT进行开发。如果它可以在swift中工作,我也可以使用任何库。这是我的功能:
func forward () {
timeGap = slider.value
let preferredTimeScale : Int32 = 1
let targetTime : CMTime = CMTimeMake(timeGap, preferredTimeScale)
player.seekToTime(targetTime, toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero)
}
提前致谢。
答案 0 :(得分:9)
这个答案很大程度上基于这个答案:https://stackoverflow.com/a/7195954/765298。任何和所有的功劳都应该去那里,因为这只是对swift的翻译。
你是正确的,当你向远处寻找未被缓冲的部分时,玩家会停下来。问题是它仍然缓冲数据,但在准备好后不会自动启动。所以,将链接的答案改写为swift:
设置观察者:
player.currentItem?.addObserver(self, forKeyPath: "playbackBufferEmpty", options: .New, context: nil)
player.currentItem?.addObserver(self, forKeyPath: "playbackLikelyToKeepUp", options: .New, context: nil)
注意,为了能够观察值,传递的self
需要从NSObject
继承。
并处理它们:
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
}
switch keyPath! {
case "playbackBufferEmpty" :
if player.currentItem!.playbackBufferEmpty {
print("no buffer")
// do something here to inform the user that the file is buffering
}
case "playbackLikelyToKeepUp" :
if player.currentItem!.playbackLikelyToKeepUp {
self.player.play()
// remove the buffering inidcator if you added it
}
}
}
您还可以从当前播放AVPlayerItem
获取有关可用时间范围的信息(如果您尚未自己创建,可以通过player.currentItem
访问它)。这使您可以向用户指示文件的哪些部分已准备就绪。
与往常一样,您可以在文档中阅读更多内容:AVPlayerItem和AVPlayer
要阅读有关键值观察(KVO)的更多信息:here