简体   繁体   English

帧更改的AVPlayer回调(观察者)

[英]AVPlayer Callback (Observer) for Frame Changed

Is there way to set up an observer / callback on an AVPlayer to get notified when the frame changes? 有没有办法在AVPlayer上设置观察者/回调以在帧变化时得到通知?

I am aware of both addBoundaryTimeObserver and addPeriodicTimeObserver however these are approximations that require me to estimate the frame rate, etc. 我知道addBoundaryTimeObserveraddPeriodicTimeObserver但是这些是需要我估计帧速率等的近似值。

There is a note that: 有一条说明:

General State Observations: You can use Key-value observing (KVO) to observe state changes to many of the player's dynamic properties, such as its currentItem or its playback rate. 一般状态观察:您可以使用键值观察(KVO)来观察许多玩家动态属性的状态变化,例如其currentItem或其回放速率。 You should register and unregister for KVO change notifications on the main thread. 您应该在主线程上注册和取消注册KVO更改通知。 This avoids the possibility of receiving a partial notification if a change is being made on another thread. 这避免了在另一个线程上进行更改时接收部分通知的可能性。 AV Foundation invokes observeValue(forKeyPath:of:change:context:) on the main thread, even if the change operation is made on another thread. 即使在另一个线程上进行了更改操作,AV Foundation也会在主线程上调用observeValue(forKeyPath:of:change:context :)。

However currentTime on AVPlayerItem is a method, not a property so I cannot use KVO for that. AVPlayerItem上的currentTime是一个方法,而不是属性,所以我不能使用KVO。

You could add an AVPlayerItemVideoOutput to your AVPlayerItem and periodically poll the output with hasNewPixelBufferForItemTime which will tell you of the arrival of a new frame. 您可以将AVPlayerItemVideoOutput添加到AVPlayerItem并使用hasNewPixelBufferForItemTime定期轮询输出,它将告诉您新帧的到达。 However you then need to acquire the frame with copyPixelBufferForItemTime , so you should probably immediately release it. 但是,您需要使用copyPixelBufferForItemTime获取帧,因此您可能应该立即释放它。 Here's an example of setting up AVPlayerItemVideoOutput . 以下是设置AVPlayerItemVideoOutput的示例。 This is polling, so you could realise late or even miss a frame change. 这是轮询,所以你可以意识到迟到甚至错过帧更改。

You could also quickly preprocess the video file (if it is a file) without decompressing the frames, to determine the frame presentation time stamps. 您还可以快速预处理视频文件(如果它文件)而不解压缩帧,以确定帧显示时间戳。 You could feed those timestamps one at a time to addBoundaryTimeObserver to decide when you'd crossed a frame boundary. 您可以一次一个地提供这些时间戳,以添加addBoundaryTimeObserver来决定何时越过帧边界。 Here's an example of parsing a video file . 这是解析视频文件的示例。

AVSampleBufferDisplayLayer , which is a lower level AVPlayerLayer , that lets you feed it video frame CMSampleBuffer s looks like a promising way to find out when a frame changes, but it doesn't seem to tell you when it has displayed one of the sample buffers you gave it. AVSampleBufferDisplayLayer ,它是一个较低级别的AVPlayerLayer ,可以让你为它提供视频帧CMSampleBuffer 看起来像一个很有前途的方法来找出帧何时发生变化,但它似乎没有告诉你何时它显示了一个样本缓冲区你给它。 And I don't think AVSampleBufferDisplayLayer handles audio, either. 我也不认为AVSampleBufferDisplayLayer处理音频。

You could also reimplement the AVPlayer playback system - then you'd be painfully (and accurately) aware of frame changes (and audio changes, and opengl/metal). 您还可以重新实现AVPlayer播放系统 - 然后您将痛苦地(并且准确地)了解帧更改(以及音频更改和opengl / metal)。 Surely that kind of effort is not required here. 当然,这里不需要那种努力。 What kind of feature are are you trying to implement exactly? 您准备实施什么样的功能?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM