[英]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. 我知道
addBoundaryTimeObserver
和addPeriodicTimeObserver
但是这些是需要我估计帧速率等的近似值。
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.