帧更改的{AVIlayer回调(观察者)

时间:2017-05-10 15:15:19

标签: ios swift avfoundation avplayer avplayeritem

有没有办法在AVPlayer上设置观察者/回调以在帧发生变化时收到通知?

我知道addBoundaryTimeObserveraddPeriodicTimeObserver这些都是需要我估算帧速率等的近似值。

有一条说明:

  

一般状态观察:您可以使用键值观察(KVO)观察许多玩家动态属性的状态变化,例如其currentItem或其播放速率。您应该在主线程上注册和取消注册KVO更改通知。这避免了在另一个线程上进行更改时接收部分通知的可能性。即使在另一个线程上进行了更改操作,AV Foundation也会在主线程上调用observeValue(forKeyPath:of:change:context :)。

currentTime上的AVPlayerItem是一种方法,而不是属性,所以我不能使用KVO。

1 个答案:

答案 0 :(得分:0)

您可以向AVPlayerItemVideoOutput添加AVPlayerItem,并定期使用hasNewPixelBufferForItemTime轮询输出,这将告诉您新帧的到达。但是,您需要使用copyPixelBufferForItemTime获取帧,因此您可能应该立即释放它。以下是设置AVPlayerItemVideoOutput的示例。这是轮询,所以你可能会意识到迟到甚至错过帧更改。

您还可以快速预处理视频文件(如果文件)而不解压缩帧,以确定帧显示时间戳。您可以将这些时间戳一次一个地提供给addBoundaryTimeObserver,以决定何时越过帧边界。以下是parsing a video file的示例。

AVSampleBufferDisplayLayer,这是一个较低级别AVPlayerLayer,可让您为其提供视频帧CMSampleBuffer 看起来,就像找出何时帧更改,但它似乎没有告诉你何时它已经显示了你给它的一个样本缓冲区。而且我认为AVSampleBufferDisplayLayer也不会处理音频。

您还可以重新实现AVPlayer播放系统 - 然后您会痛苦地(并且准确地)了解帧更改(以及音频更改和opengl / metal)。当然,这里不需要那种努力。您准备实施哪种功能?