我正在尝试在AVPlayer的时间轴中观察一个时间。
我在主队列上尝试过;这没有用。然后根据this stack overflow post的建议切换到后台队列;两者都没有。寻找有效的解决方案或解释为何不起作用。
text/plain
//add boundary time notification to global queue
avLayer.player!.addBoundaryTimeObserver(forTimes: [NSValue(time: avLayer.player!.currentItem!.duration)], queue: DispatchQueue.main){
self.avLayer.player!.pause()
}
更新:在保留对观察者返回值的强引用之后,我在回调中设置了一个断点。它仍然无法正常工作。
//add boundary time notification to background queue
avLayer.player!.addBoundaryTimeObserver(forTimes: [NSValue(time: avLayer.player!.currentItem!.duration)], queue: DispatchQueue.global(qos: .userInteractive)){
self.avLayer.player!.pause()
}
答案 0 :(得分:3)
可能有两个问题:
addBoundaryTimeObserver
的文档规定:
只要您希望播放器调用时间观察者,就必须保持对返回值的强烈引用
由于您的初始代码未保留对返回的内部不透明时间观察者的引用,因此观察者可能会立即释放,因此永远不会被调用。
确保您注册的观察时间实际上具有正确的值:
asset
的持续时间也可能是未知的,或者是不精确的估计(同样,请参见AVAsset.duration
的文档)。 因此,您注册观察的时间可能永远都不会达到(请注意,可以通过插入CMTimeShow(duration)
来方便地检查时间)
解决方法:
如果您只是想在达到playerItem的结尾时停止播放器,则将player.actionAtItemEnd
设置为pause
可能就足够了
如果在项目结束时需要执行一些自定义逻辑,请使用playerItem作为对象注册AVPlayerItemDidPlayToEndTime
通知的观察者。此机制独立于可能的持续时间,因此希望更加可靠
答案 1 :(得分:1)
var player = AVPlayer()
var token: Any?
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let u = "https... "
let playerItem = AVPlayerItem(url: URL(string: u)!)
player = AVPlayer(playerItem: playerItem)
player.play()
token = player.addBoundaryTimeObserver(
forTimes: [0.5 as NSValue],
queue: DispatchQueue.main) { [weak self] in
self?.spinner.stopAnimating()
print("The audio is in fact beginning about now...")
}
}
完美运行。
使用较小的值作为快速解决方案来查找“开始”。