将电影中的帧绘制到CGBitmapContext中

时间:2013-10-24 18:43:56

标签: avplayer avasset avplayerlayer cgbitmapcontext

我有一个应用需要将视频/电影中的帧渲染为具有任意CGAffineTransform的CGBitmapContext。我希望它有一个不错的帧率,至少20fps。

我尝试过使用AVURLAsset和[AVAssetImageGenerator copyCGImageAtTime:],并且正如此方法的文档明确指出的那样,它很慢,有时会降低到5fps。

有什么更好的方法可以做到这一点?我想我可以用AVPlayerLayer设置一个AVPlayer,然后用我的变换使用[CGLayer renderInContext:]。这会有用吗?或者当AVPlayerLayer注意到它没有显示在屏幕上时,它可能没有运行?

还有其他建议吗?

1 个答案:

答案 0 :(得分:1)

我最终通过以下方式从视频帧中获得可爱,快速的UIImages:
1)使用视频的URL创建AVURLAsset 2)使用资产创建AVAssetReader 3)设置读者的timeRange属性 4)使用资产中的第一个轨道创建AVAssetReaderTrackOutput 5)将输出添加到阅读器。

然后为每一帧:
6)调用[output copyNextSampleBuffer]。
7)将样本缓冲区传递给CMSampleBufferGetImageBuffer 8)将图像缓冲区传递给CVPixelBufferLockBaseAddress,只读
9)使用CVPixelBufferGetBaseAddress获取图像缓冲区的基址 10)使用图像缓冲区中的维度调用CGBitmapContextCreate,将基址作为CGBitmap像素的位置传递。
11)调用CGBitmapContextCreateImage以获取CGImageRef。

我很高兴地发现这对于擦洗效果非常好。如果用户想要返回视频的早期部分,只需创建一个具有新时间范围的新AVAssetReader即可。这很快!