有没有办法在AVPlayer
上设置观察者/回调以在帧发生变化时收到通知?
我知道addBoundaryTimeObserver
和addPeriodicTimeObserver
这些都是需要我估算帧速率等的近似值。
有一条说明:
一般状态观察:您可以使用键值观察(KVO)观察许多玩家动态属性的状态变化,例如其currentItem或其播放速率。您应该在主线程上注册和取消注册KVO更改通知。这避免了在另一个线程上进行更改时接收部分通知的可能性。即使在另一个线程上进行了更改操作,AV Foundation也会在主线程上调用observeValue(forKeyPath:of:change:context :)。
currentTime
上的AVPlayerItem
是一种方法,而不是属性,所以我不能使用KVO。
答案 0 :(得分:0)
您可以向AVPlayerItemVideoOutput
添加AVPlayerItem
,并定期使用hasNewPixelBufferForItemTime
轮询输出,这将告诉您新帧的到达。但是,您需要使用copyPixelBufferForItemTime
获取帧,因此您可能应该立即释放它。以下是设置AVPlayerItemVideoOutput的示例。这是轮询,所以你可能会意识到迟到甚至错过帧更改。
您还可以快速预处理视频文件(如果是文件)而不解压缩帧,以确定帧显示时间戳。您可以将这些时间戳一次一个地提供给addBoundaryTimeObserver
,以决定何时越过帧边界。以下是parsing a video file的示例。
AVSampleBufferDisplayLayer
,这是一个较低级别AVPlayerLayer
,可让您为其提供视频帧CMSampleBuffer
看起来,就像找出何时帧更改,但它似乎没有告诉你何时它已经显示了你给它的一个样本缓冲区。而且我认为AVSampleBufferDisplayLayer
也不会处理音频。
您还可以重新实现AVPlayer
播放系统 - 然后您会痛苦地(并且准确地)了解帧更改(以及音频更改和opengl / metal)。当然,这里不需要那种努力。您准备实施哪种功能?