Отрисовка кадров из фильма в CGBitmapContext

У меня есть приложение, которому нужно отображать кадры из видео/фильма в CGBitmapContext с произвольным CGAffineTransform. Я бы хотел, чтобы у него была приличная частота кадров, хотя бы 20 кадров в секунду.

Я пытался использовать AVURLAsset и [AVAssetImageGenerator copyCGImageAtTime:], и, как четко указано в документации по этому методу, он довольно медленный, иногда снижая скорость до 5 кадров в секунду.

Как лучше это сделать? Я ДУМАЮ, что могу настроить AVPlayer с AVPlayerLayer, а затем использовать [CGLayer renderInContext:] с моим преобразованием. Будет ли это работать? Или, возможно, AVPlayerLayer не запускается, когда замечает, что он не отображается на экране?

Какие еще способы предложить?


person Christopher Schardt    schedule 24.10.2013    source источник


Ответы (1)


В итоге я получил красивые и быстрые UIImages из кадров видео следующим образом:
1) Создал AVURLAsset с URL-адресом видео.
2) Создал AVAssetReader с активом.
3) Установил для читателей timeRange свойство.
4) Создание AVAssetReaderTrackOutput с первой дорожкой из актива.
5) Добавление вывода в средство чтения.

Затем для каждого кадра:
6) Вызов [output copyNextSampleBuffer].
7) Передача буфера сэмпла в CMSampleBufferGetImageBuffer.
8) Передача буфера изображения в CVPixelBufferLockBaseAddress, только для чтения
9) Получение базовый адрес буфера изображения с CVPixelBufferGetBaseAddress
10) Вызов CGBitmapContextCreate с размерами из буфера изображения, передача базового адреса в качестве местоположения пикселей CGBitmap.
11) Вызов CGBitmapContextCreateImage для получения CGImageRef.

Я был очень рад обнаружить, что это работает на удивление хорошо для очистки. Если пользователь хочет вернуться к более ранней части видео, просто создайте новый AVAssetReader с новым временным диапазоном и вперед. Это довольно быстро!

person Christopher Schardt    schedule 05.04.2014