为啥 AVPlayer 边界时间观察器不起作用?

Posted

技术标签:

【中文标题】为啥 AVPlayer 边界时间观察器不起作用?【英文标题】:Why is AVPlayer Boundary Time Observer not working?为什么 AVPlayer 边界时间观察器不起作用? 【发布时间】:2019-01-19 18:28:30 【问题描述】:

我试图在我的 AVPlayer 的时间轴上观察一个时间。

我在主队列上试过这个;这没有用。然后我按照this stack overflow post 的建议切换到后台队列;这两者都没有。寻找可行的解决方案或解释为什么这不起作用。

//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()
                    

更新:在保留对观察者返回值的强引用后,我在回调中设置了断点。它仍然无法正常工作。

 //add boundary time notification
                    boundaryTimeObserver = avLayer.player!.addBoundaryTimeObserver(forTimes: [NSValue(time: avLayer.player!.currentItem!.duration)], queue: DispatchQueue.main)

                        self.avLayer.player!.pause()
                    

【问题讨论】:

【参考方案1】:

2019 简单例子..

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...")
    

完美运行。

重要..它不会找到“0”

使用较小的值来查找“开始”作为快速解决方案。

【讨论】:

非常感谢关于找不到 0 的附加说明【参考方案2】:

可能有两个问题:

    正如addBoundaryTimeObserver 的文档所述:

    只要您希望播放器调用时间观察器,您就必须保持对返回值的强引用

    由于您的初始代码没有保留对返回的内部不透明时间观察者的引用,因此观察者可能会立即被释放,因此永远不会被调用。

    确保您注册观察的时间实际上具有正确的值:

    playerItem.duration 可能是不确定的(请参阅此属性的文档) 即使是 playerItem 的 asset 的持续时间也可能是未知的,或者是不精确的估计,具体取决于资产的类型和加载状态(同样,请参阅 AVAsset.duration 的文档)。

    因此,您注册观察的时间可能永远无法达到(请注意,可以通过插入 CMTimeShow(duration) 轻松检查时间)

解决此问题的方法:

如果你只是想在 playerItem 结束时停止播放器,将 player.actionAtItemEnd 设置为 pause 可能就足够了

如果您需要在项目结束时执行一些自定义逻辑,请使用 playerItem 作为对象注册AVPlayerItemDidPlayToEndTime 通知的观察者。这种机制独立于可能不精确的持续时间,因此希望更可靠

【讨论】:

我保留了引用,但仍然没有调用观察者。请查看更新。

以上是关于为啥 AVPlayer 边界时间观察器不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

Flutter:为啥这个流构建器不起作用?

Opengl为啥这个着色器不起作用?

为啥我的直系后代选择器不起作用?

为啥这个 CSS 选择器不起作用:a:hover ~ span?

为啥边界半径对图像不起作用?

为啥带有多个可观察对象的 RxSwift concat 似乎不起作用?